mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-28 05:47:52 +00:00
Add comment TODO, format code and remove unused import
This commit is contained in:
parent
1a0ccbc08d
commit
d796a3f7c0
@ -91,7 +91,7 @@ export const AddGroup = ({ address, open, setOpen }) => {
|
||||
if (!name) throw new Error('Please provide a name');
|
||||
if (!description) throw new Error('Please provide a description');
|
||||
|
||||
const fee = await getFee('CREATE_GROUP');
|
||||
const fee = await getFee('CREATE_GROUP'); // TODO translate
|
||||
await show({
|
||||
message: 'Would you like to perform an CREATE_GROUP transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
|
@ -101,7 +101,7 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
|
||||
const handleJoinGroup = async (group, isOpen) => {
|
||||
try {
|
||||
const groupId = group.groupId;
|
||||
const fee = await getFee('JOIN_GROUP');
|
||||
const fee = await getFee('JOIN_GROUP'); // TODO translate
|
||||
await show({
|
||||
message: 'Would you like to perform an JOIN_GROUP transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
|
@ -129,7 +129,7 @@ export const BlockedUsersModal = () => {
|
||||
executeEvent('updateChatMessagesWithBlocks', true);
|
||||
}
|
||||
} catch (error) {
|
||||
setOpenSnackGlobal(true);
|
||||
setOpenSnackGlobal(true); // TODO translate
|
||||
setInfoSnackCustom({
|
||||
type: 'error',
|
||||
message: error?.message || 'Unable to block user',
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { useMemo } from "react";
|
||||
import DOMPurify from "dompurify";
|
||||
import "react-quill/dist/quill.snow.css";
|
||||
import "react-quill/dist/quill.core.css";
|
||||
import "react-quill/dist/quill.bubble.css";
|
||||
import { Box, styled } from "@mui/material";
|
||||
import { convertQortalLinks } from "../../../utils/qortalLink";
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import DOMPurify from 'dompurify';
|
||||
import 'react-quill/dist/quill.snow.css';
|
||||
import 'react-quill/dist/quill.core.css';
|
||||
import 'react-quill/dist/quill.bubble.css';
|
||||
import { Box, styled } from '@mui/material';
|
||||
import { convertQortalLinks } from '../../../utils/qortalLink';
|
||||
|
||||
const CrowdfundInlineContent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
display: 'flex',
|
||||
fontFamily: 'Mulish',
|
||||
fontSize: '19px',
|
||||
fontWeight: 400,
|
||||
letterSpacing: 0,
|
||||
color: theme.palette.text.primary,
|
||||
width: '100%'
|
||||
width: '100%',
|
||||
}));
|
||||
|
||||
export const DisplayHtml = ({ html, textColor }: any) => {
|
||||
@ -29,6 +28,7 @@ export const DisplayHtml = ({ html, textColor }: any) => {
|
||||
}, [html]);
|
||||
|
||||
if (!cleanContent) return null;
|
||||
|
||||
return (
|
||||
<CrowdfundInlineContent>
|
||||
<div
|
||||
@ -36,7 +36,7 @@ export const DisplayHtml = ({ html, textColor }: any) => {
|
||||
style={{
|
||||
color: textColor || 'white',
|
||||
fontWeight: 400,
|
||||
fontSize: '16px'
|
||||
fontSize: '16px',
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: cleanContent }}
|
||||
/>
|
||||
|
@ -45,7 +45,6 @@ import { formatDate, formatTimestamp } from '../../../utils/time';
|
||||
import LazyLoad from '../../../common/LazyLoad';
|
||||
import { delay } from '../../../utils/helpers';
|
||||
import { NewThread } from './NewThread';
|
||||
import { getBaseApi } from '../../../background';
|
||||
import {
|
||||
decryptPublishes,
|
||||
getTempPublish,
|
||||
@ -55,15 +54,11 @@ import CheckSVG from '../../../assets/svgs/Check.svg';
|
||||
import SortSVG from '../../../assets/svgs/Sort.svg';
|
||||
import ArrowDownSVG from '../../../assets/svgs/ArrowDown.svg';
|
||||
import { LoadingSnackbar } from '../../Snackbar/LoadingSnackbar';
|
||||
import {
|
||||
executeEvent,
|
||||
subscribeToEvent,
|
||||
unsubscribeFromEvent,
|
||||
} from '../../../utils/events';
|
||||
import { executeEvent } from '../../../utils/events';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
import { getArbitraryEndpointReact, getBaseApiReact } from '../../../App';
|
||||
import { WrapperUserAction } from '../../WrapperUserAction';
|
||||
import { addDataPublishesFunc, getDataPublishesFunc } from '../Group';
|
||||
|
||||
const filterOptions = ['Recently active', 'Newest', 'Oldest'];
|
||||
|
||||
export const threadIdentifier = 'DOCUMENT';
|
||||
@ -183,7 +178,7 @@ export const GroupMail = ({
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
} finally {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
@ -266,7 +261,6 @@ export const GroupMail = ({
|
||||
} else {
|
||||
sorted = fullArrayMsg.sort((a: any, b: any) => a.created - b.created);
|
||||
}
|
||||
|
||||
setAllThreads(sorted);
|
||||
} catch (error) {
|
||||
console.log({ error });
|
||||
@ -376,6 +370,7 @@ export const GroupMail = ({
|
||||
);
|
||||
setRecentThreads(sorted);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
// dispatch(setIsLoadingCustom(null));
|
||||
@ -444,7 +439,6 @@ export const GroupMail = ({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setMembers(members);
|
||||
} catch (error) {
|
||||
console.log({ error });
|
||||
@ -754,7 +748,9 @@ export const GroupMail = ({
|
||||
>
|
||||
{thread?.threadData?.title}
|
||||
</ThreadSingleTitle>
|
||||
|
||||
<Spacer height="10px" />
|
||||
|
||||
{filterMode === 'Recently active' && (
|
||||
<div
|
||||
style={{
|
||||
@ -799,7 +795,7 @@ export const GroupMail = ({
|
||||
sx={{
|
||||
color: 'white',
|
||||
fontSize: '12px',
|
||||
}}
|
||||
}} // TODO translate
|
||||
>
|
||||
Last page
|
||||
</Typography>
|
||||
|
@ -1,52 +1,47 @@
|
||||
import {
|
||||
AppBar,
|
||||
Button,
|
||||
Toolbar,
|
||||
Typography,
|
||||
Box,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import { styled } from "@mui/system";
|
||||
import { Typography, Box, TextField } from '@mui/material';
|
||||
import { styled } from '@mui/system';
|
||||
|
||||
export const InstanceContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
backgroundColor: "var(--color-instance)",
|
||||
height: "59px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
backgroundColor: 'var(--color-instance)',
|
||||
height: '59px',
|
||||
flexShrink: 0,
|
||||
justifyContent: "space-between",
|
||||
justifyContent: 'space-between',
|
||||
}));
|
||||
|
||||
export const MailContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
height: "calc(100vh - 78px)",
|
||||
overflow: "hidden",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: 'calc(100vh - 78px)',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
|
||||
export const MailBody = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
width: "100%",
|
||||
height: "calc(100% - 59px)",
|
||||
// overflow: 'auto !important'
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
height: 'calc(100% - 59px)',
|
||||
}));
|
||||
|
||||
export const MailBodyInner = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "50%",
|
||||
height: "100%",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '50%',
|
||||
height: '100%',
|
||||
}));
|
||||
|
||||
export const MailBodyInnerHeader = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
height: "25px",
|
||||
marginTop: "50px",
|
||||
marginBottom: "35px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: "11px",
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '25px',
|
||||
marginTop: '50px',
|
||||
marginBottom: '35px',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '11px',
|
||||
}));
|
||||
|
||||
export const MailBodyInnerScroll = styled(Box)`
|
||||
@ -84,163 +79,174 @@ export const MailBodyInnerScroll = styled(Box)`
|
||||
`;
|
||||
|
||||
export const ComposeContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "150px",
|
||||
alignItems: "center",
|
||||
gap: "7px",
|
||||
height: "100%",
|
||||
cursor: "pointer",
|
||||
transition: "0.2s background-color",
|
||||
justifyContent: "center",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(67, 68, 72, 1)",
|
||||
display: 'flex',
|
||||
width: '150px',
|
||||
alignItems: 'center',
|
||||
gap: '7px',
|
||||
height: '100%',
|
||||
cursor: 'pointer',
|
||||
transition: '0.2s background-color',
|
||||
justifyContent: 'center',
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(67, 68, 72, 1)',
|
||||
},
|
||||
}));
|
||||
|
||||
export const ComposeContainerBlank = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "150px",
|
||||
alignItems: "center",
|
||||
gap: "7px",
|
||||
height: "100%",
|
||||
display: 'flex',
|
||||
width: '150px',
|
||||
alignItems: 'center',
|
||||
gap: '7px',
|
||||
height: '100%',
|
||||
}));
|
||||
|
||||
export const ComposeP = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "15px",
|
||||
fontSize: '15px',
|
||||
fontWeight: 500,
|
||||
}));
|
||||
|
||||
export const ComposeIcon = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
cursor: "pointer",
|
||||
});
|
||||
export const ArrowDownIcon = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
cursor: "pointer",
|
||||
});
|
||||
export const MailIconImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
export const ComposeIcon = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
export const MailMessageRowInfoImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
export const ArrowDownIcon = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
export const MailIconImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
|
||||
export const MailMessageRowInfoImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
|
||||
export const SelectInstanceContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "17px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '17px',
|
||||
}));
|
||||
|
||||
export const SelectInstanceContainerInner = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "3px",
|
||||
cursor: "pointer",
|
||||
padding: "8px",
|
||||
transition: "all 0.2s",
|
||||
"&:hover": {
|
||||
borderRadius: "8px",
|
||||
background: "#434448",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '3px',
|
||||
cursor: 'pointer',
|
||||
padding: '8px',
|
||||
transition: 'all 0.2s',
|
||||
'&:hover': {
|
||||
borderRadius: '8px',
|
||||
background: '#434448',
|
||||
},
|
||||
}));
|
||||
|
||||
export const SelectInstanceContainerFilterInner = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "3px",
|
||||
cursor: "pointer",
|
||||
padding: "8px",
|
||||
transition: "all 0.2s"
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '3px',
|
||||
cursor: 'pointer',
|
||||
padding: '8px',
|
||||
transition: 'all 0.2s',
|
||||
}));
|
||||
|
||||
|
||||
export const InstanceLabel = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontSize: '16px',
|
||||
fontWeight: 500,
|
||||
color: "#FFFFFF33",
|
||||
color: '#FFFFFF33',
|
||||
}));
|
||||
|
||||
export const InstanceP = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontSize: '16px',
|
||||
fontWeight: 500,
|
||||
}));
|
||||
|
||||
export const MailMessageRowContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
justifyContent: "space-between",
|
||||
borderRadius: "56px 5px 10px 56px",
|
||||
paddingRight: "15px",
|
||||
transition: "background 0.2s",
|
||||
gap: "10px",
|
||||
"&:hover": {
|
||||
background: "#434448",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
justifyContent: 'space-between',
|
||||
borderRadius: '56px 5px 10px 56px',
|
||||
paddingRight: '15px',
|
||||
transition: 'background 0.2s',
|
||||
gap: '10px',
|
||||
'&:hover': {
|
||||
background: '#434448',
|
||||
},
|
||||
}));
|
||||
|
||||
export const MailMessageRowProfile = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
justifyContent: "flex-start",
|
||||
gap: "10px",
|
||||
width: "50%",
|
||||
overflow: "hidden",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
justifyContent: 'flex-start',
|
||||
gap: '10px',
|
||||
width: '50%',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
|
||||
export const MailMessageRowInfo = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
justifyContent: "flex-start",
|
||||
gap: "7px",
|
||||
width: "50%",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
justifyContent: 'flex-start',
|
||||
gap: '7px',
|
||||
width: '50%',
|
||||
}));
|
||||
|
||||
export const MailMessageRowInfoStatusNotDecrypted = styled(Typography)(
|
||||
({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontSize: '16px',
|
||||
fontWeight: 900,
|
||||
textTransform: "uppercase",
|
||||
paddingTop: "2px",
|
||||
textTransform: 'uppercase',
|
||||
paddingTop: '2px',
|
||||
})
|
||||
);
|
||||
|
||||
export const MailMessageRowInfoStatusRead = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontSize: '16px',
|
||||
fontWeight: 300,
|
||||
}));
|
||||
|
||||
export const MessageExtraInfo = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2px",
|
||||
overflow: "hidden",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2px',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
|
||||
export const MessageExtraName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontSize: '16px',
|
||||
fontWeight: 900,
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
|
||||
export const MessageExtraDate = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "15px",
|
||||
fontSize: '15px',
|
||||
fontWeight: 500,
|
||||
}));
|
||||
|
||||
export const MessagesContainer = styled(Box)(({ theme }) => ({
|
||||
width: "460px",
|
||||
maxWidth: "90%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "12px",
|
||||
width: '460px',
|
||||
maxWidth: '90%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '12px',
|
||||
}));
|
||||
|
||||
export const InstanceListParent = styled(Box)`
|
||||
@ -254,18 +260,21 @@ export const InstanceListParent = styled(Box)`
|
||||
background-color: var(--color-instance-popover-bg);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
`;
|
||||
|
||||
export const InstanceListHeader = styled(Box)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background-color: var(--color-instance-popover-bg);
|
||||
`;
|
||||
|
||||
export const InstanceFooter = styled(Box)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
export const InstanceListContainer = styled(Box)`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@ -301,126 +310,132 @@ export const InstanceListContainer = styled(Box)`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const InstanceListContainerRowLabelContainer = styled(Box)(
|
||||
({ theme }) => ({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
height: "50px",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
height: '50px',
|
||||
})
|
||||
);
|
||||
|
||||
export const InstanceListContainerRow = styled(Box)(({ theme }) => ({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
height: "50px",
|
||||
cursor: "pointer",
|
||||
transition: "0.2s background",
|
||||
"&:hover": {
|
||||
background: "rgba(67, 68, 72, 1)",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
height: '50px',
|
||||
cursor: 'pointer',
|
||||
transition: '0.2s background',
|
||||
'&:hover': {
|
||||
background: 'rgba(67, 68, 72, 1)',
|
||||
},
|
||||
flexShrink: 0,
|
||||
}));
|
||||
|
||||
export const InstanceListContainerRowCheck = styled(Box)(({ theme }) => ({
|
||||
width: "47px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: '47px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}));
|
||||
|
||||
export const InstanceListContainerRowMain = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
paddingRight: "30px",
|
||||
overflow: "hidden",
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
paddingRight: '30px',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
|
||||
export const CloseParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "20px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '20px',
|
||||
}));
|
||||
|
||||
export const InstanceListContainerRowMainP = styled(Typography)(
|
||||
({ theme }) => ({
|
||||
fontWeight: 500,
|
||||
fontSize: "16px",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
fontSize: '16px',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
})
|
||||
);
|
||||
|
||||
export const InstanceListContainerRowCheckIcon = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
export const InstanceListContainerRowCheckIcon = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
export const InstanceListContainerRowGroupIcon = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
export const InstanceListContainerRowGroupIcon = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
export const TypeInAliasTextfield = styled(TextField)({
|
||||
width: "340px", // Adjust the width as needed
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "rgba(30, 30, 32, 1)",
|
||||
border: "none",
|
||||
outline: "none",
|
||||
width: '340px', // Adjust the width as needed
|
||||
borderRadius: '5px',
|
||||
backgroundColor: 'rgba(30, 30, 32, 1)',
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
input: {
|
||||
fontSize: 16,
|
||||
color: "white",
|
||||
"&::placeholder": {
|
||||
color: 'white',
|
||||
'&::placeholder': {
|
||||
fontSize: 16,
|
||||
color: "rgba(255, 255, 255, 0.2)",
|
||||
color: 'rgba(255, 255, 255, 0.2)',
|
||||
},
|
||||
border: "none",
|
||||
outline: "none",
|
||||
padding: "10px",
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
padding: '10px',
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
border: "none",
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
border: 'none',
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: "none",
|
||||
'&:hover fieldset': {
|
||||
border: 'none',
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: "none",
|
||||
'&.Mui-focused fieldset': {
|
||||
border: 'none',
|
||||
},
|
||||
},
|
||||
"& .MuiInput-underline:before": {
|
||||
borderBottom: "none",
|
||||
'& .MuiInput-underline:before': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
"& .MuiInput-underline:hover:not(.Mui-disabled):before": {
|
||||
borderBottom: "none",
|
||||
'& .MuiInput-underline:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
"& .MuiInput-underline:after": {
|
||||
borderBottom: "none",
|
||||
'& .MuiInput-underline:after': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
});
|
||||
|
||||
export const NewMessageCloseImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
cursor: "pointer",
|
||||
export const NewMessageCloseImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
export const NewMessageHeaderP = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "18px",
|
||||
fontSize: '18px',
|
||||
fontWeight: 600,
|
||||
}));
|
||||
|
||||
export const NewMessageInputRow = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
borderBottom: "3px solid rgba(237, 239, 241, 1)",
|
||||
width: "100%",
|
||||
paddingBottom: "6px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
borderBottom: '3px solid rgba(237, 239, 241, 1)',
|
||||
width: '100%',
|
||||
paddingBottom: '6px',
|
||||
}));
|
||||
export const NewMessageInputLabelP = styled(Typography)`
|
||||
color: rgba(84, 84, 84, 0.7);
|
||||
@ -444,25 +459,25 @@ export const AliasLabelP = styled(Typography)`
|
||||
}
|
||||
`;
|
||||
export const NewMessageAliasContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "12px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
}));
|
||||
export const AttachmentContainer = styled(Box)(({ theme }) => ({
|
||||
height: "36px",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
height: '36px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
export const NewMessageAttachmentImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
cursor: "pointer",
|
||||
padding: "10px",
|
||||
border: "1px dashed #646464",
|
||||
export const NewMessageAttachmentImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
cursor: 'pointer',
|
||||
padding: '10px',
|
||||
border: '1px dashed #646464',
|
||||
});
|
||||
|
||||
export const NewMessageSendButton = styled(Box)`
|
||||
@ -582,34 +597,36 @@ export const ShowMessageButtonP = styled(Typography)`
|
||||
color: white;
|
||||
`;
|
||||
|
||||
export const ShowMessageButtonImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
cursor: "pointer",
|
||||
export const ShowMessageButtonImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
export const MailAttachmentImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
export const MailAttachmentImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
export const AliasAvatarImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
|
||||
export const AliasAvatarImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
export const MoreImg = styled("img")({
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
userSelect: "none",
|
||||
objectFit: "contain",
|
||||
transition: "0.2s all",
|
||||
"&:hover": {
|
||||
transform: "scale(1.3)",
|
||||
|
||||
export const MoreImg = styled('img')({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
userSelect: 'none',
|
||||
objectFit: 'contain',
|
||||
transition: '0.2s all',
|
||||
'&:hover': {
|
||||
transform: 'scale(1.3)',
|
||||
},
|
||||
});
|
||||
|
||||
@ -625,17 +642,19 @@ export const MoreP = styled(Typography)`
|
||||
letter-spacing: -0.16px;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
export const ThreadContainerFullWidth = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
export const ThreadContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
maxWidth: "95%",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
maxWidth: '95%',
|
||||
}));
|
||||
|
||||
export const GroupNameP = styled(Typography)`
|
||||
@ -648,7 +667,7 @@ export const GroupNameP = styled(Typography)`
|
||||
`;
|
||||
|
||||
export const AllThreadP = styled(Typography)`
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@ -668,9 +687,10 @@ height: 76px;
|
||||
align-items: center;
|
||||
transition: 0.2s all;
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.20)
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
`;
|
||||
|
||||
export const SingleTheadMessageParent = styled(Box)`
|
||||
border-radius: 35px 4px 4px 35px;
|
||||
background: #434448;
|
||||
@ -680,22 +700,20 @@ cursor: pointer;
|
||||
margin-bottom: 5px;
|
||||
height: 76px;
|
||||
align-items: center;
|
||||
|
||||
`;
|
||||
|
||||
export const ThreadInfoColumn = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "170px",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '170px',
|
||||
gap: '2px',
|
||||
marginLeft: '10px',
|
||||
height: '100%',
|
||||
justifyContent: 'center'
|
||||
justifyContent: 'center',
|
||||
}));
|
||||
|
||||
|
||||
export const ThreadInfoColumnNameP = styled(Typography)`
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
font-family: Roboto;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
@ -705,8 +723,9 @@ white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
export const ThreadInfoColumnbyP = styled('span')`
|
||||
color: rgba(255, 255, 255, 0.80);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-family: Roboto;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
@ -715,15 +734,16 @@ line-height: normal;
|
||||
`;
|
||||
|
||||
export const ThreadInfoColumnTime = styled(Typography)`
|
||||
color: rgba(255, 255, 255, 0.80);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-family: Roboto;
|
||||
font-size: 15px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
`
|
||||
`;
|
||||
|
||||
export const ThreadSingleTitle = styled(Typography)`
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
font-family: Roboto;
|
||||
font-size: 23px;
|
||||
font-style: normal;
|
||||
@ -732,17 +752,19 @@ line-height: normal;
|
||||
white-space: wrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
`
|
||||
`;
|
||||
|
||||
export const ThreadSingleLastMessageP = styled(Typography)`
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
font-family: Roboto;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
`
|
||||
`;
|
||||
|
||||
export const ThreadSingleLastMessageSpanP = styled('span')`
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
font-family: Roboto;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
@ -754,24 +776,22 @@ export const GroupContainer = styled(Box)`
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
|
||||
|
||||
`
|
||||
`;
|
||||
|
||||
export const CloseContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "50px",
|
||||
overflow: "hidden",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
transition: "0.2s background-color",
|
||||
justifyContent: "center",
|
||||
display: 'flex',
|
||||
width: '50px',
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
transition: '0.2s background-color',
|
||||
justifyContent: 'center',
|
||||
position: 'absolute',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
height: '50px',
|
||||
borderRadius: '0px 12px 0px 0px',
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(162, 31, 31, 1)",
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(162, 31, 31, 1)',
|
||||
},
|
||||
}));
|
@ -191,7 +191,7 @@ export const NewThread = ({
|
||||
}
|
||||
if (!groupInfo) {
|
||||
errorMsg = 'Cannot access group information';
|
||||
}
|
||||
} // TODO translate
|
||||
|
||||
// if (!description) missingFields.push('subject')
|
||||
if (missingFields.length > 0) {
|
||||
|
@ -1,18 +1,24 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { createEditor } from 'slate';
|
||||
import { withReact, Slate, Editable, RenderElementProps, RenderLeafProps } from 'slate-react';
|
||||
import {
|
||||
withReact,
|
||||
Slate,
|
||||
Editable,
|
||||
RenderElementProps,
|
||||
RenderLeafProps,
|
||||
} from 'slate-react';
|
||||
|
||||
type ExtendedRenderElementProps = RenderElementProps & { mode?: string }
|
||||
type ExtendedRenderElementProps = RenderElementProps & { mode?: string };
|
||||
|
||||
export const renderElement = ({
|
||||
attributes,
|
||||
children,
|
||||
element,
|
||||
mode
|
||||
mode,
|
||||
}: ExtendedRenderElementProps) => {
|
||||
switch (element.type) {
|
||||
case 'block-quote':
|
||||
return <blockquote {...attributes}>{children}</blockquote>
|
||||
return <blockquote {...attributes}>{children}</blockquote>;
|
||||
case 'heading-2':
|
||||
return (
|
||||
<h2
|
||||
@ -22,7 +28,7 @@ export const renderElement = ({
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
)
|
||||
);
|
||||
case 'heading-3':
|
||||
return (
|
||||
<h3
|
||||
@ -32,21 +38,21 @@ export const renderElement = ({
|
||||
>
|
||||
{children}
|
||||
</h3>
|
||||
)
|
||||
);
|
||||
case 'code-block':
|
||||
return (
|
||||
<pre {...attributes} className="code-block">
|
||||
<code>{children}</code>
|
||||
</pre>
|
||||
)
|
||||
);
|
||||
case 'code-line':
|
||||
return <div {...attributes}>{children}</div>
|
||||
return <div {...attributes}>{children}</div>;
|
||||
case 'link':
|
||||
return (
|
||||
<a href={element.url} {...attributes}>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<p
|
||||
@ -56,24 +62,23 @@ export const renderElement = ({
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const renderLeaf = ({ attributes, children, leaf }: RenderLeafProps) => {
|
||||
let el = children
|
||||
let el = children;
|
||||
|
||||
if (leaf.bold) {
|
||||
el = <strong>{el}</strong>
|
||||
el = <strong>{el}</strong>;
|
||||
}
|
||||
|
||||
if (leaf.italic) {
|
||||
el = <em>{el}</em>
|
||||
el = <em>{el}</em>;
|
||||
}
|
||||
|
||||
if (leaf.underline) {
|
||||
el = <u>{el}</u>
|
||||
el = <u>{el}</u>;
|
||||
}
|
||||
|
||||
if (leaf.link) {
|
||||
@ -81,39 +86,35 @@ export const renderLeaf = ({ attributes, children, leaf }: RenderLeafProps) => {
|
||||
<a href={leaf.link} {...attributes}>
|
||||
{el}
|
||||
</a>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return <span {...attributes}>{el}</span>
|
||||
}
|
||||
return <span {...attributes}>{el}</span>;
|
||||
};
|
||||
|
||||
interface ReadOnlySlateProps {
|
||||
content: any
|
||||
mode?: string
|
||||
content: any;
|
||||
mode?: string;
|
||||
}
|
||||
const ReadOnlySlate: React.FC<ReadOnlySlateProps> = ({ content, mode }) => {
|
||||
const [load, setLoad] = useState(false)
|
||||
const editor = useMemo(() => withReact(createEditor()), [])
|
||||
const value = useMemo(() => content, [content])
|
||||
const [load, setLoad] = useState(false);
|
||||
const editor = useMemo(() => withReact(createEditor()), []);
|
||||
const value = useMemo(() => content, [content]);
|
||||
|
||||
const performUpdate = useCallback(async () => {
|
||||
setLoad(true)
|
||||
setLoad(true);
|
||||
await new Promise<void>((res) => {
|
||||
setTimeout(() => {
|
||||
res()
|
||||
res();
|
||||
}, 250);
|
||||
})
|
||||
setLoad(false)
|
||||
}, [])
|
||||
});
|
||||
setLoad(false);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
performUpdate();
|
||||
}, [value]);
|
||||
|
||||
|
||||
|
||||
|
||||
performUpdate()
|
||||
}, [value])
|
||||
|
||||
if(load) return null
|
||||
if (load) return null;
|
||||
|
||||
return (
|
||||
<Slate editor={editor} value={value} onChange={() => {}}>
|
||||
@ -123,7 +124,7 @@ const ReadOnlySlate: React.FC<ReadOnlySlateProps> = ({ content, mode }) => {
|
||||
renderLeaf={renderLeaf}
|
||||
/>
|
||||
</Slate>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default ReadOnlySlate;
|
@ -1,8 +1,8 @@
|
||||
import React, { useState } from "react";
|
||||
import { Avatar, Box, IconButton } from "@mui/material";
|
||||
import DOMPurify from "dompurify";
|
||||
import { useState } from 'react';
|
||||
import { Avatar, Box, IconButton } from '@mui/material';
|
||||
import DOMPurify from 'dompurify';
|
||||
import FormatQuoteIcon from '@mui/icons-material/FormatQuote';
|
||||
import MoreSVG from '../../../assets/svgs/More.svg'
|
||||
import MoreSVG from '../../../assets/svgs/More.svg';
|
||||
|
||||
import {
|
||||
MoreImg,
|
||||
@ -11,20 +11,18 @@ import {
|
||||
ThreadInfoColumn,
|
||||
ThreadInfoColumnNameP,
|
||||
ThreadInfoColumnTime,
|
||||
} from "./Mail-styles";
|
||||
import { Spacer } from "../../../common/Spacer";
|
||||
import { DisplayHtml } from "./DisplayHtml";
|
||||
import { formatTimestampForum } from "../../../utils/time";
|
||||
import ReadOnlySlate from "./ReadOnlySlate";
|
||||
import { MessageDisplay } from "../../Chat/MessageDisplay";
|
||||
import { getBaseApi } from "../../../background";
|
||||
import { getBaseApiReact } from "../../../App";
|
||||
import { WrapperUserAction } from "../../WrapperUserAction";
|
||||
} from './Mail-styles';
|
||||
import { Spacer } from '../../../common/Spacer';
|
||||
import { formatTimestampForum } from '../../../utils/time';
|
||||
import ReadOnlySlate from './ReadOnlySlate';
|
||||
import { MessageDisplay } from '../../Chat/MessageDisplay';
|
||||
import { getBaseApiReact } from '../../../App';
|
||||
import { WrapperUserAction } from '../../WrapperUserAction';
|
||||
|
||||
export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
|
||||
const [expandAttachments, setExpandAttachments] = useState<boolean>(false);
|
||||
|
||||
let cleanHTML = "";
|
||||
let cleanHTML = '';
|
||||
if (message?.htmlContent) {
|
||||
cleanHTML = DOMPurify.sanitize(message.htmlContent);
|
||||
}
|
||||
@ -32,37 +30,49 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
|
||||
return (
|
||||
<SingleTheadMessageParent
|
||||
sx={{
|
||||
height: "auto",
|
||||
alignItems: "flex-start",
|
||||
cursor: "default",
|
||||
borderRadius: '35px 4px 4px 4px'
|
||||
height: 'auto',
|
||||
alignItems: 'flex-start',
|
||||
cursor: 'default',
|
||||
borderRadius: '35px 4px 4px 4px',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "flex-start",
|
||||
width: '100%'
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
gap: "10px",
|
||||
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<WrapperUserAction disabled={myName === message?.name} address={undefined} name={message?.name}>
|
||||
<Avatar sx={{
|
||||
<WrapperUserAction
|
||||
disabled={myName === message?.name}
|
||||
address={undefined}
|
||||
name={message?.name}
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: '50px',
|
||||
width: '50px'
|
||||
}} src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${message?.name}/qortal_avatar?async=true`} alt={message?.name}>{message?.name?.charAt(0)}</Avatar>
|
||||
width: '50px',
|
||||
}}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${message?.name}/qortal_avatar?async=true`}
|
||||
alt={message?.name}
|
||||
>
|
||||
{message?.name?.charAt(0)}
|
||||
</Avatar>
|
||||
</WrapperUserAction>
|
||||
<ThreadInfoColumn>
|
||||
|
||||
<WrapperUserAction disabled={myName === message?.name} address={undefined} name={message?.name}>
|
||||
<WrapperUserAction
|
||||
disabled={myName === message?.name}
|
||||
address={undefined}
|
||||
name={message?.name}
|
||||
>
|
||||
<ThreadInfoColumnNameP>{message?.name}</ThreadInfoColumnNameP>
|
||||
</WrapperUserAction>
|
||||
<ThreadInfoColumnTime>
|
||||
@ -71,37 +81,40 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
|
||||
</ThreadInfoColumn>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{message?.attachments?.length > 0 && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
marginTop: "10px",
|
||||
width: '100%',
|
||||
marginTop: '10px',
|
||||
}}
|
||||
>
|
||||
{message?.attachments
|
||||
.map((file: any, index: number) => {
|
||||
const isFirst = index === 0
|
||||
{message?.attachments.map((file: any, index: number) => {
|
||||
const isFirst = index === 0;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: expandAttachments ? "flex" : !expandAttachments && isFirst ? 'flex' : 'none',
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
width: "100%",
|
||||
display: expandAttachments
|
||||
? 'flex'
|
||||
: !expandAttachments && isFirst
|
||||
? 'flex'
|
||||
: 'none',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "5px",
|
||||
cursor: "pointer",
|
||||
width: "auto",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '5px',
|
||||
cursor: 'pointer',
|
||||
width: 'auto',
|
||||
}}
|
||||
>
|
||||
{/* <FileElement
|
||||
@ -128,75 +141,84 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
|
||||
{message?.attachments?.length > 1 && isFirst && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "5px",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '5px',
|
||||
}}
|
||||
onClick={() => {
|
||||
setExpandAttachments(prev => !prev);
|
||||
setExpandAttachments((prev) => !prev);
|
||||
}}
|
||||
>
|
||||
<MoreImg
|
||||
sx={{
|
||||
marginLeft: "5px",
|
||||
marginLeft: '5px',
|
||||
transform: expandAttachments
|
||||
? "rotate(180deg)"
|
||||
: "unset",
|
||||
? 'rotate(180deg)'
|
||||
: 'unset',
|
||||
}}
|
||||
src={MoreSVG}
|
||||
/>
|
||||
<MoreP>
|
||||
{expandAttachments ? 'hide' : `(${message?.attachments?.length - 1} more)`}
|
||||
|
||||
{expandAttachments
|
||||
? 'hide'
|
||||
: `(${message?.attachments?.length - 1} more)`}
|
||||
</MoreP>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})
|
||||
}
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<Spacer height="20px" />
|
||||
|
||||
{message?.reply?.textContentV2 && (
|
||||
<>
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
opacity: 0.7,
|
||||
borderRadius: '5px',
|
||||
border: '1px solid gray',
|
||||
boxSizing: 'border-box',
|
||||
padding: '5px'
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
gap: "10px",
|
||||
|
||||
padding: '5px',
|
||||
}}
|
||||
>
|
||||
|
||||
<Avatar sx={{
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}} src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${message?.reply?.name}/qortal_avatar?async=true`} alt={message?.reply?.name}>{message?.reply?.name?.charAt(0)}</Avatar>
|
||||
width: '30px',
|
||||
}}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${message?.reply?.name}/qortal_avatar?async=true`}
|
||||
alt={message?.reply?.name}
|
||||
>
|
||||
{message?.reply?.name?.charAt(0)}
|
||||
</Avatar>
|
||||
<ThreadInfoColumn>
|
||||
<ThreadInfoColumnNameP sx={{
|
||||
fontSize: '14px'
|
||||
}}>{message?.reply?.name}</ThreadInfoColumnNameP>
|
||||
|
||||
<ThreadInfoColumnNameP
|
||||
sx={{
|
||||
fontSize: '14px',
|
||||
}}
|
||||
>
|
||||
{message?.reply?.name}
|
||||
</ThreadInfoColumnNameP>
|
||||
</ThreadInfoColumn>
|
||||
</Box>
|
||||
<MessageDisplay htmlContent={message?.reply?.textContentV2} />
|
||||
</Box>
|
||||
<Spacer height="20px" />
|
||||
</>
|
||||
|
||||
)}
|
||||
|
||||
{message?.textContent && (
|
||||
@ -208,22 +230,18 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
|
||||
{message?.htmlContent && (
|
||||
<div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
|
||||
)}
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end'
|
||||
}}>
|
||||
<IconButton
|
||||
onClick={() => openNewPostWithQuote(message)}
|
||||
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<IconButton onClick={() => openNewPostWithQuote(message)}>
|
||||
<FormatQuoteIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
|
||||
|
||||
</SingleTheadMessageParent>
|
||||
);
|
||||
};
|
||||
|
@ -1,32 +1,33 @@
|
||||
import React from "react";
|
||||
import ReactQuill, { Quill } from "react-quill";
|
||||
import "react-quill/dist/quill.snow.css";
|
||||
import ImageResize from "quill-image-resize-module-react";
|
||||
import './texteditor.css'
|
||||
Quill.register("modules/imageResize", ImageResize);
|
||||
import ReactQuill, { Quill } from 'react-quill';
|
||||
import 'react-quill/dist/quill.snow.css';
|
||||
import ImageResize from 'quill-image-resize-module-react';
|
||||
import './texteditor.css';
|
||||
|
||||
Quill.register('modules/imageResize', ImageResize);
|
||||
|
||||
const modules = {
|
||||
imageResize: {
|
||||
parchment: Quill.import("parchment"),
|
||||
modules: ["Resize", "DisplaySize"],
|
||||
parchment: Quill.import('parchment'),
|
||||
modules: ['Resize', 'DisplaySize'],
|
||||
},
|
||||
toolbar: [
|
||||
["bold", "italic", "underline", "strike"], // styled text
|
||||
["blockquote", "code-block"], // blocks
|
||||
['bold', 'italic', 'underline', 'strike'], // styled text
|
||||
['blockquote', 'code-block'], // blocks
|
||||
[{ header: 1 }, { header: 2 }], // custom button values
|
||||
[{ list: "ordered" }, { list: "bullet" }], // lists
|
||||
[{ script: "sub" }, { script: "super" }], // superscript/subscript
|
||||
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
|
||||
[{ direction: "rtl" }], // text direction
|
||||
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
|
||||
[{ list: 'ordered' }, { list: 'bullet' }], // lists
|
||||
[{ script: 'sub' }, { script: 'super' }], // superscript/subscript
|
||||
[{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
||||
[{ direction: 'rtl' }], // text direction
|
||||
[{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }], // custom button values
|
||||
[{ color: [] }, { background: [] }], // dropdown with defaults
|
||||
[{ font: [] }], // font family
|
||||
[{ align: [] }], // text align
|
||||
["clean"], // remove formatting
|
||||
['clean'], // remove formatting
|
||||
// ["image"], // image
|
||||
],
|
||||
};
|
||||
|
||||
export const TextEditor = ({ inlineContent, setInlineContent }: any) => {
|
||||
return (
|
||||
<ReactQuill
|
||||
|
@ -467,6 +467,7 @@ export const Thread = ({
|
||||
}
|
||||
setMessages(fullArrayMsg);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
}
|
||||
},
|
||||
@ -700,7 +701,7 @@ export const Thread = ({
|
||||
);
|
||||
}}
|
||||
disabled={!hasPreviousPage}
|
||||
variant="contained"
|
||||
variant="contained" // TODO translate
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
|
@ -2218,7 +2218,8 @@ export const Group = ({
|
||||
}}
|
||||
>
|
||||
No group selected
|
||||
</Typography>
|
||||
</Typography>{' '}
|
||||
// TODO translate
|
||||
</Box>
|
||||
)}
|
||||
|
||||
|
@ -69,7 +69,7 @@ export const GroupInvites = ({ myAddress, setOpenAddGroup }) => {
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: '1rem',
|
||||
}}
|
||||
}} // TODO translate
|
||||
>
|
||||
Group Invites{' '}
|
||||
{groupsWithJoinRequests?.length > 0 &&
|
||||
|
@ -82,6 +82,7 @@ export const GroupJoinRequests = ({
|
||||
);
|
||||
setGroupsWithJoinRequests(res);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -138,7 +139,7 @@ export const GroupJoinRequests = ({
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: '1rem',
|
||||
}}
|
||||
}} // TODO translate
|
||||
>
|
||||
Join Requests{' '}
|
||||
{filteredJoinRequests?.filter((group) => group?.data?.length > 0)
|
||||
|
@ -1,22 +1,27 @@
|
||||
import React, { useState } from "react";
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Badge,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import ForumIcon from "@mui/icons-material/Forum";
|
||||
import GroupIcon from "@mui/icons-material/Group";
|
||||
import { ArrowDownIcon } from "../../assets/Icons/ArrowDownIcon";
|
||||
import { NotificationIcon2 } from "../../assets/Icons/NotificationIcon2";
|
||||
import { ChatIcon } from "../../assets/Icons/ChatIcon";
|
||||
import { ThreadsIcon } from "../../assets/Icons/ThreadsIcon";
|
||||
import { MembersIcon } from "../../assets/Icons/MembersIcon";
|
||||
} from '@mui/material';
|
||||
import { ArrowDownIcon } from '../../assets/Icons/ArrowDownIcon';
|
||||
import { NotificationIcon2 } from '../../assets/Icons/NotificationIcon2';
|
||||
import { ChatIcon } from '../../assets/Icons/ChatIcon';
|
||||
import { ThreadsIcon } from '../../assets/Icons/ThreadsIcon';
|
||||
import { MembersIcon } from '../../assets/Icons/MembersIcon';
|
||||
|
||||
export const GroupMenu = ({ setGroupSection, groupSection, setOpenManageMembers, goToAnnouncements, goToChat, hasUnreadChat, hasUnreadAnnouncements }) => {
|
||||
export const GroupMenu = ({
|
||||
setGroupSection,
|
||||
groupSection,
|
||||
setOpenManageMembers,
|
||||
goToAnnouncements,
|
||||
goToChat,
|
||||
hasUnreadChat,
|
||||
hasUnreadAnnouncements,
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const open = Boolean(anchorEl);
|
||||
|
||||
@ -31,72 +36,103 @@ export const GroupMenu = ({ setGroupSection, groupSection, setOpenManageMembers,
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
marginTop: '14px',
|
||||
marginBottom: '14px'
|
||||
marginBottom: '14px',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
aria-controls={open ? "home-menu" : undefined}
|
||||
aria-controls={open ? 'home-menu' : undefined}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={open ? "true" : undefined}
|
||||
aria-expanded={open ? 'true' : undefined}
|
||||
onClick={handleClick}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
width: "148px",
|
||||
borderRadius: "5px",
|
||||
fontSize: "12px",
|
||||
backgroundColor: 'var(--bg-primary)',
|
||||
width: '148px',
|
||||
borderRadius: '5px',
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: "#fff",
|
||||
textTransform: "none",
|
||||
color: '#fff',
|
||||
textTransform: 'none',
|
||||
padding: '5px',
|
||||
height: '25px'
|
||||
height: '25px',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "6px",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
width: '100%'
|
||||
display: 'flex',
|
||||
gap: '6px',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "6px",
|
||||
alignItems: "center",
|
||||
display: 'flex',
|
||||
gap: '6px',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{groupSection === "announcement" &&(
|
||||
<> <NotificationIcon2 color={hasUnreadAnnouncements || hasUnreadChat ? 'var(--danger)' : 'white'} /> {" Announcements"}</>
|
||||
{groupSection === 'announcement' && (
|
||||
<>
|
||||
{' '}
|
||||
<NotificationIcon2
|
||||
color={
|
||||
hasUnreadAnnouncements || hasUnreadChat
|
||||
? 'var(--danger)'
|
||||
: 'white'
|
||||
}
|
||||
/>{' '}
|
||||
{' Announcements'}
|
||||
</>
|
||||
)}
|
||||
{groupSection === "chat" &&(
|
||||
<> <ChatIcon color={hasUnreadAnnouncements || hasUnreadChat ? 'var(--danger)' : 'white'} /> {" Group Chats"}</>
|
||||
{groupSection === 'chat' && (
|
||||
<>
|
||||
{' '}
|
||||
<ChatIcon
|
||||
color={
|
||||
hasUnreadAnnouncements || hasUnreadChat
|
||||
? 'var(--danger)'
|
||||
: 'white'
|
||||
}
|
||||
/>{' '}
|
||||
{' Group Chats'}
|
||||
</>
|
||||
)}
|
||||
{groupSection === "forum" &&(
|
||||
<> <ThreadsIcon color={hasUnreadAnnouncements || hasUnreadChat ? 'var(--danger)' : 'white'} /> {" Threads"}</>
|
||||
{groupSection === 'forum' && (
|
||||
<>
|
||||
{' '}
|
||||
<ThreadsIcon
|
||||
color={
|
||||
hasUnreadAnnouncements || hasUnreadChat
|
||||
? 'var(--danger)'
|
||||
: 'white'
|
||||
}
|
||||
/>{' '}
|
||||
{' Threads'}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<ArrowDownIcon color="white" />
|
||||
</Box>
|
||||
</Button>
|
||||
|
||||
<Menu
|
||||
id="home-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
MenuListProps={{
|
||||
"aria-labelledby": "basic-button",
|
||||
'aria-labelledby': 'basic-button',
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
@ -108,93 +144,109 @@ export const GroupMenu = ({ setGroupSection, groupSection, setOpenManageMembers,
|
||||
backgroundColor: 'var(--bg-primary)',
|
||||
color: '#fff',
|
||||
width: '148px',
|
||||
borderRadius: '5px'
|
||||
borderRadius: '5px',
|
||||
},
|
||||
},
|
||||
|
||||
}}
|
||||
sx={{
|
||||
marginTop: '10px'
|
||||
marginTop: '10px',
|
||||
}}
|
||||
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
goToChat()
|
||||
goToChat();
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<ChatIcon color={hasUnreadChat ? 'var(--danger)' : "#fff"} />
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: '24px !important',
|
||||
}}
|
||||
>
|
||||
<ChatIcon color={hasUnreadChat ? 'var(--danger)' : '#fff'} />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
<ListItemText
|
||||
sx={{
|
||||
'& .MuiTypography-root': {
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: hasUnreadChat ? "var(--danger)" :"#fff"
|
||||
color: hasUnreadChat ? 'var(--danger)' : '#fff',
|
||||
},
|
||||
}} primary="Chat" />
|
||||
}}
|
||||
primary="Chat"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
goToAnnouncements()
|
||||
goToAnnouncements();
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<NotificationIcon2 color={hasUnreadAnnouncements ? 'var(--danger)' : "#fff" } />
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: '24px !important',
|
||||
}}
|
||||
>
|
||||
<NotificationIcon2
|
||||
color={hasUnreadAnnouncements ? 'var(--danger)' : '#fff'}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
<ListItemText
|
||||
sx={{
|
||||
'& .MuiTypography-root': {
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: hasUnreadAnnouncements ? "var(--danger)" :"#fff"
|
||||
color: hasUnreadAnnouncements ? 'var(--danger)' : '#fff',
|
||||
},
|
||||
}} primary="Announcements" />
|
||||
}}
|
||||
primary="Announcements"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setGroupSection("forum");
|
||||
setGroupSection('forum');
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<ThreadsIcon color={"#fff"} />
|
||||
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: '24px !important',
|
||||
}}
|
||||
>
|
||||
<ThreadsIcon color={'#fff'} />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
<ListItemText
|
||||
sx={{
|
||||
'& .MuiTypography-root': {
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
},
|
||||
}} primary="Threads" />
|
||||
}}
|
||||
primary="Threads"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setOpenManageMembers(true)
|
||||
setOpenManageMembers(true);
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<MembersIcon sx={{ color: "#fff" }} />
|
||||
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: '24px !important',
|
||||
}}
|
||||
>
|
||||
<MembersIcon sx={{ color: '#fff' }} />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
<ListItemText
|
||||
sx={{
|
||||
'& .MuiTypography-root': {
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
},
|
||||
}} primary="Members" />
|
||||
}}
|
||||
primary="Members"
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Box>
|
||||
|
@ -1,13 +1,6 @@
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Input,
|
||||
MenuItem,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
} from '@mui/material';
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Input, MenuItem, Select, SelectChangeEvent } from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
import { Label } from './AddGroup';
|
||||
import { getFee } from '../../background';
|
||||
@ -34,6 +27,7 @@ export const InviteMember = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
// TODO translate
|
||||
setInfoSnack({
|
||||
type: 'success',
|
||||
message: `Successfully invited ${value}. It may take a couple of minutes for the changes to propagate`,
|
||||
|
@ -1,16 +1,31 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Avatar, Box, Button, ListItem, ListItemAvatar, ListItemButton, ListItemText, Popover } from '@mui/material';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Popover,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
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';
|
||||
|
||||
export const getMemberInvites = async (groupNumber) => {
|
||||
const response = await fetch(`${getBaseApiReact()}/groups/bans/${groupNumber}?limit=0`);
|
||||
const response = await fetch(
|
||||
`${getBaseApiReact()}/groups/bans/${groupNumber}?limit=0`
|
||||
);
|
||||
const groupData = await response.json();
|
||||
return groupData;
|
||||
}
|
||||
};
|
||||
|
||||
const getNames = async (listOfMembers, includeNoNames) => {
|
||||
let members = [];
|
||||
@ -21,13 +36,13 @@ const getNames = async (listOfMembers, includeNoNames) => {
|
||||
if (name) {
|
||||
members.push({ ...member, name });
|
||||
} else if (includeNoNames) {
|
||||
members.push({ ...member, name: name || "" });
|
||||
members.push({ ...member, name: name || '' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
};
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
@ -49,7 +64,7 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (groupId) {
|
||||
@ -69,14 +84,16 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
|
||||
const handleCancelBan = async (address) => {
|
||||
try {
|
||||
const fee = await getFee('CANCEL_GROUP_BAN')
|
||||
// TODO translate
|
||||
const fee = await getFee('CANCEL_GROUP_BAN');
|
||||
await show({
|
||||
message: "Would you like to perform a CANCEL_GROUP_BAN transaction?" ,
|
||||
publishFee: fee.fee + ' QORT'
|
||||
})
|
||||
setIsLoadingUnban(true)
|
||||
message: 'Would you like to perform a CANCEL_GROUP_BAN transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingUnban(true);
|
||||
new Promise((res, rej) => {
|
||||
window.sendMessage("cancelBan", {
|
||||
window
|
||||
.sendMessage('cancelBan', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
})
|
||||
@ -85,15 +102,16 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
res(response);
|
||||
setIsLoadingUnban(false);
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully unbanned user. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully unbanned user. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
handlePopoverClose();
|
||||
setOpenSnack(true);
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -101,20 +119,18 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setIsLoadingUnban(false)
|
||||
}
|
||||
setIsLoadingUnban(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rowRenderer = ({ index, key, parent, style }) => {
|
||||
const member = bans[index];
|
||||
@ -135,36 +151,47 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
anchorEl={popoverAnchor}
|
||||
onClose={handlePopoverClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
style={{ marginTop: "8px" }}
|
||||
style={{ marginTop: '8px' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "325px",
|
||||
height: "250px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
width: '325px',
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '10px',
|
||||
}}
|
||||
>
|
||||
<LoadingButton loading={isLoadingUnban}
|
||||
<LoadingButton
|
||||
loading={isLoadingUnban}
|
||||
loadingPosition="start"
|
||||
variant="contained" onClick={()=> handleCancelBan(member?.offender)}>Cancel Ban</LoadingButton>
|
||||
variant="contained"
|
||||
onClick={() => handleCancelBan(member?.offender)}
|
||||
>
|
||||
Cancel Ban
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Popover>
|
||||
<ListItemButton onClick={(event) => handlePopoverOpen(event, index)}>
|
||||
<ListItemButton
|
||||
onClick={(event) => handlePopoverOpen(event, index)}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar
|
||||
alt={member?.name}
|
||||
src={member?.name ? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true` : ''}
|
||||
src={
|
||||
member?.name
|
||||
? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={member?.name || member?.offender} />
|
||||
@ -179,7 +206,16 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
return (
|
||||
<div>
|
||||
<p>Ban list</p>
|
||||
<div style={{ position: 'relative', height: '500px', width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
height: '500px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 1,
|
||||
}}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<List
|
||||
@ -196,4 +232,4 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -230,7 +230,7 @@ export const ListOfGroupPromotions = () => {
|
||||
.catch((error) => {
|
||||
rej(error.message || 'An error occurred');
|
||||
});
|
||||
});
|
||||
}); // TODO translate
|
||||
setInfoSnack({
|
||||
type: 'success',
|
||||
message:
|
||||
|
@ -1,16 +1,31 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Avatar, Box, Button, ListItem, ListItemAvatar, ListItemButton, ListItemText, Popover } from '@mui/material';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Popover,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
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';
|
||||
|
||||
export const getMemberInvites = async (groupNumber) => {
|
||||
const response = await fetch(`${getBaseApiReact()}/groups/invites/group/${groupNumber}?limit=0`);
|
||||
const response = await fetch(
|
||||
`${getBaseApiReact()}/groups/invites/group/${groupNumber}?limit=0`
|
||||
);
|
||||
const groupData = await response.json();
|
||||
return groupData;
|
||||
}
|
||||
};
|
||||
|
||||
const getNames = async (listOfMembers, includeNoNames) => {
|
||||
let members = [];
|
||||
@ -21,20 +36,25 @@ const getNames = async (listOfMembers, includeNoNames) => {
|
||||
if (name) {
|
||||
members.push({ ...member, name });
|
||||
} else if (includeNoNames) {
|
||||
members.push({ ...member, name: name || "" });
|
||||
members.push({ ...member, name: name || '' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
};
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: 50,
|
||||
});
|
||||
|
||||
export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
export const ListOfInvites = ({
|
||||
groupId,
|
||||
setInfoSnack,
|
||||
setOpenSnack,
|
||||
show,
|
||||
}) => {
|
||||
const [invites, setInvites] = 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
|
||||
@ -50,7 +70,7 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (groupId) {
|
||||
@ -70,22 +90,25 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
|
||||
const handleCancelInvitation = async (address) => {
|
||||
try {
|
||||
const fee = await getFee('CANCEL_GROUP_INVITE')
|
||||
// TODO translate
|
||||
const fee = await getFee('CANCEL_GROUP_INVITE');
|
||||
await show({
|
||||
message: "Would you like to perform a CANCEL_GROUP_INVITE transaction?" ,
|
||||
publishFee: fee.fee + ' QORT'
|
||||
})
|
||||
setIsLoadingCancelInvite(true)
|
||||
message: 'Would you like to perform a CANCEL_GROUP_INVITE transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingCancelInvite(true);
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("cancelInvitationToGroup", {
|
||||
window
|
||||
.sendMessage('cancelInvitationToGroup', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully canceled invitation. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully canceled invitation. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -94,7 +117,7 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -102,20 +125,18 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setIsLoadingCancelInvite(false)
|
||||
}
|
||||
setIsLoadingCancelInvite(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rowRenderer = ({ index, key, parent, style }) => {
|
||||
const member = invites[index];
|
||||
@ -136,36 +157,47 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
anchorEl={popoverAnchor}
|
||||
onClose={handlePopoverClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
style={{ marginTop: "8px" }}
|
||||
style={{ marginTop: '8px' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "325px",
|
||||
height: "250px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
width: '325px',
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '10px',
|
||||
}}
|
||||
>
|
||||
<LoadingButton loading={isLoadingCancelInvite}
|
||||
<LoadingButton
|
||||
loading={isLoadingCancelInvite}
|
||||
loadingPosition="start"
|
||||
variant="contained" onClick={()=> handleCancelInvitation(member?.invitee)}>Cancel Invitation</LoadingButton>
|
||||
variant="contained"
|
||||
onClick={() => handleCancelInvitation(member?.invitee)}
|
||||
>
|
||||
Cancel Invitation
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Popover>
|
||||
<ListItemButton onClick={(event) => handlePopoverOpen(event, index)}>
|
||||
<ListItemButton
|
||||
onClick={(event) => handlePopoverOpen(event, index)}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar
|
||||
alt={member?.name}
|
||||
src={member?.name ? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true` : ''}
|
||||
src={
|
||||
member?.name
|
||||
? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={member?.name || member?.invitee} />
|
||||
@ -180,7 +212,16 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
return (
|
||||
<div>
|
||||
<p>Invitees list</p>
|
||||
<div style={{ position: 'relative', height: '500px', width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
height: '500px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 1,
|
||||
}}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<List
|
||||
@ -197,4 +238,4 @@ export const ListOfInvites = ({ groupId, setInfoSnack, setOpenSnack, show }) =>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1,16 +1,31 @@
|
||||
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||
import { Avatar, Box, Button, ListItem, ListItemAvatar, ListItemButton, ListItemText, Popover } from '@mui/material';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
|
||||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Popover,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
List,
|
||||
} from 'react-virtualized';
|
||||
import { getNameInfo } from './Group';
|
||||
import { getBaseApi, getFee } from '../../background';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { MyContext, getBaseApiReact } from '../../App';
|
||||
|
||||
export const getMemberInvites = async (groupNumber) => {
|
||||
const response = await fetch(`${getBaseApiReact()}/groups/joinrequests/${groupNumber}?limit=0`);
|
||||
const response = await fetch(
|
||||
`${getBaseApiReact()}/groups/joinrequests/${groupNumber}?limit=0`
|
||||
);
|
||||
const groupData = await response.json();
|
||||
return groupData;
|
||||
}
|
||||
};
|
||||
|
||||
const getNames = async (listOfMembers, includeNoNames) => {
|
||||
let members = [];
|
||||
@ -19,24 +34,29 @@ const getNames = async (listOfMembers, includeNoNames) => {
|
||||
if (member.joiner) {
|
||||
const name = await getNameInfo(member.joiner);
|
||||
if (name) {
|
||||
members.push({ ...member, name: name || "" });
|
||||
members.push({ ...member, name: name || '' });
|
||||
} else if (includeNoNames) {
|
||||
members.push({ ...member, name: name || "" });
|
||||
members.push({ ...member, name: name || '' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
};
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: 50,
|
||||
});
|
||||
|
||||
export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }) => {
|
||||
export const ListOfJoinRequests = ({
|
||||
groupId,
|
||||
setInfoSnack,
|
||||
setOpenSnack,
|
||||
show,
|
||||
}) => {
|
||||
const [invites, setInvites] = useState([]);
|
||||
const {txList, setTxList} = useContext(MyContext)
|
||||
const { txList, setTxList } = useContext(MyContext);
|
||||
|
||||
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
|
||||
@ -51,7 +71,7 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (groupId) {
|
||||
@ -71,14 +91,15 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
|
||||
const handleAcceptJoinRequest = async (address) => {
|
||||
try {
|
||||
const fee = await getFee('GROUP_INVITE')
|
||||
const fee = await getFee('GROUP_INVITE'); // TODO translate
|
||||
await show({
|
||||
message: "Would you like to perform a GROUP_INVITE transaction?" ,
|
||||
publishFee: fee.fee + ' QORT'
|
||||
})
|
||||
setIsLoadingAccept(true)
|
||||
message: 'Would you like to perform a GROUP_INVITE transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingAccept(true);
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("inviteToGroup", {
|
||||
window
|
||||
.sendMessage('inviteToGroup', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
inviteTime: 10800,
|
||||
@ -87,8 +108,9 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
if (!response?.error) {
|
||||
setIsLoadingAccept(false);
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully accepted join request. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully accepted join request. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -111,7 +133,7 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
}
|
||||
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -119,25 +141,28 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error?.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error?.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setIsLoadingAccept(false)
|
||||
}
|
||||
setIsLoadingAccept(false);
|
||||
}
|
||||
};
|
||||
|
||||
const rowRenderer = ({ index, key, parent, style }) => {
|
||||
const member = invites[index];
|
||||
const findJoinRequsetInTxList = txList?.find((tx)=> tx?.groupId === groupId && tx?.qortalAddress === member?.joiner && tx?.type === 'join-request-accept')
|
||||
if(findJoinRequsetInTxList) return null
|
||||
const findJoinRequsetInTxList = txList?.find(
|
||||
(tx) =>
|
||||
tx?.groupId === groupId &&
|
||||
tx?.qortalAddress === member?.joiner &&
|
||||
tx?.type === 'join-request-accept'
|
||||
);
|
||||
if (findJoinRequsetInTxList) return null;
|
||||
return (
|
||||
<CellMeasurer
|
||||
key={key}
|
||||
@ -154,36 +179,47 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
anchorEl={popoverAnchor}
|
||||
onClose={handlePopoverClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
style={{ marginTop: "8px" }}
|
||||
style={{ marginTop: '8px' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "325px",
|
||||
height: "250px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
width: '325px',
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '10px',
|
||||
}}
|
||||
>
|
||||
<LoadingButton loading={isLoadingAccept}
|
||||
<LoadingButton
|
||||
loading={isLoadingAccept}
|
||||
loadingPosition="start"
|
||||
variant="contained" onClick={()=> handleAcceptJoinRequest(member?.joiner)}>Accept</LoadingButton>
|
||||
variant="contained"
|
||||
onClick={() => handleAcceptJoinRequest(member?.joiner)}
|
||||
>
|
||||
Accept
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Popover>
|
||||
<ListItemButton onClick={(event) => handlePopoverOpen(event, index)}>
|
||||
<ListItemButton
|
||||
onClick={(event) => handlePopoverOpen(event, index)}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar
|
||||
alt={member?.name}
|
||||
src={member?.name ? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true` : ''}
|
||||
src={
|
||||
member?.name
|
||||
? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={member?.name || member?.joiner} />
|
||||
@ -198,7 +234,16 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
return (
|
||||
<div>
|
||||
<p>Join request list</p>
|
||||
<div style={{ position: 'relative', height: '500px', width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
height: '500px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 1,
|
||||
}}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<List
|
||||
@ -215,4 +260,4 @@ export const ListOfJoinRequests = ({ groupId, setInfoSnack, setOpenSnack, show }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1,29 +1,29 @@
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Popover,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import React, { useRef, useState } from "react";
|
||||
} from '@mui/material';
|
||||
import { useRef, useState } from 'react';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
List,
|
||||
} from "react-virtualized";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import { getBaseApi, getFee } from "../../background";
|
||||
import { getBaseApiReact } from "../../App";
|
||||
} from 'react-virtualized';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { getFee } from '../../background';
|
||||
import { getBaseApiReact } from '../../App';
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: 50,
|
||||
});
|
||||
|
||||
const ListOfMembers = ({
|
||||
members,
|
||||
groupId,
|
||||
@ -40,7 +40,6 @@ const ListOfMembers = ({
|
||||
const [isLoadingMakeAdmin, setIsLoadingMakeAdmin] = useState(false);
|
||||
const [isLoadingRemoveAdmin, setIsLoadingRemoveAdmin] = useState(false);
|
||||
|
||||
|
||||
const listRef = useRef();
|
||||
|
||||
const handlePopoverOpen = (event, index) => {
|
||||
@ -55,23 +54,25 @@ const ListOfMembers = ({
|
||||
|
||||
const handleKick = async (address) => {
|
||||
try {
|
||||
const fee = await getFee("GROUP_KICK");
|
||||
const fee = await getFee('GROUP_KICK');
|
||||
await show({
|
||||
message: "Would you like to perform a GROUP_KICK transaction?",
|
||||
publishFee: fee.fee + " QORT",
|
||||
message: 'Would you like to perform a GROUP_KICK transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
|
||||
setIsLoadingKick(true);
|
||||
new Promise((res, rej) => {
|
||||
window.sendMessage("kickFromGroup", {
|
||||
window
|
||||
.sendMessage('kickFromGroup', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully kicked member from group. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully kicked member from group. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -79,7 +80,7 @@ const ListOfMembers = ({
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -87,29 +88,30 @@ const ListOfMembers = ({
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoadingKick(false);
|
||||
}
|
||||
};
|
||||
const handleBan = async (address) => {
|
||||
try {
|
||||
const fee = await getFee("GROUP_BAN");
|
||||
const fee = await getFee('GROUP_BAN'); // TODO translate
|
||||
await show({
|
||||
message: "Would you like to perform a GROUP_BAN transaction?",
|
||||
publishFee: fee.fee + " QORT",
|
||||
message: 'Would you like to perform a GROUP_BAN transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingBan(true);
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("banFromGroup", {
|
||||
window
|
||||
.sendMessage('banFromGroup', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
rBanTime: 0,
|
||||
@ -117,8 +119,9 @@ const ListOfMembers = ({
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully banned member from group. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully banned member from group. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -126,7 +129,7 @@ const ListOfMembers = ({
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -134,13 +137,12 @@ const ListOfMembers = ({
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
} finally {
|
||||
@ -150,22 +152,24 @@ const ListOfMembers = ({
|
||||
|
||||
const makeAdmin = async (address) => {
|
||||
try {
|
||||
const fee = await getFee("ADD_GROUP_ADMIN");
|
||||
const fee = await getFee('ADD_GROUP_ADMIN');
|
||||
await show({
|
||||
message: "Would you like to perform a ADD_GROUP_ADMIN transaction?",
|
||||
publishFee: fee.fee + " QORT",
|
||||
message: 'Would you like to perform a ADD_GROUP_ADMIN transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingMakeAdmin(true);
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("makeAdmin", {
|
||||
window
|
||||
.sendMessage('makeAdmin', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully made member an admin. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully made member an admin. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -173,7 +177,7 @@ const ListOfMembers = ({
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -181,13 +185,12 @@ const ListOfMembers = ({
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
} finally {
|
||||
@ -197,22 +200,24 @@ const ListOfMembers = ({
|
||||
|
||||
const removeAdmin = async (address) => {
|
||||
try {
|
||||
const fee = await getFee("REMOVE_GROUP_ADMIN");
|
||||
const fee = await getFee('REMOVE_GROUP_ADMIN');
|
||||
await show({
|
||||
message: "Would you like to perform a REMOVE_GROUP_ADMIN transaction?",
|
||||
publishFee: fee.fee + " QORT",
|
||||
message: 'Would you like to perform a REMOVE_GROUP_ADMIN transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
setIsLoadingRemoveAdmin(true);
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("removeAdmin", {
|
||||
window
|
||||
.sendMessage('removeAdmin', {
|
||||
groupId,
|
||||
qortalAddress: address,
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.error) {
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully removed member as an admin. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully removed member as an admin. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
@ -220,7 +225,7 @@ const ListOfMembers = ({
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -228,13 +233,12 @@ const ListOfMembers = ({
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
} finally {
|
||||
@ -260,24 +264,24 @@ const ListOfMembers = ({
|
||||
anchorEl={popoverAnchor}
|
||||
onClose={handlePopoverClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
style={{ marginTop: "8px" }}
|
||||
style={{ marginTop: '8px' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "325px",
|
||||
height: "250px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
width: '325px',
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '10px',
|
||||
}}
|
||||
>
|
||||
{isOwner && (
|
||||
@ -336,21 +340,28 @@ const ListOfMembers = ({
|
||||
<ListItemAvatar>
|
||||
<Avatar
|
||||
alt={member?.name || member?.member}
|
||||
src={member?.name ? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true` : ''}
|
||||
src={
|
||||
member?.name
|
||||
? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${member?.name}/qortal_avatar?async=true`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
id={""}
|
||||
id={''}
|
||||
primary={member?.name || member?.member}
|
||||
/>
|
||||
{member?.isAdmin && (
|
||||
<Typography sx={{
|
||||
<Typography
|
||||
sx={{
|
||||
color: 'white',
|
||||
marginLeft: 'auto'
|
||||
}}>Admin</Typography>
|
||||
marginLeft: 'auto',
|
||||
}}
|
||||
>
|
||||
Admin
|
||||
</Typography>
|
||||
)}
|
||||
</ListItemButton>
|
||||
|
||||
</ListItem>
|
||||
</div>
|
||||
)}
|
||||
@ -363,11 +374,11 @@ const ListOfMembers = ({
|
||||
<p>Member list</p>
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
height: "500px",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
position: 'relative',
|
||||
height: '500px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 1,
|
||||
}}
|
||||
>
|
||||
|
@ -42,7 +42,7 @@ export const ListOfThreadPostsWatched = () => {
|
||||
rej(response.error);
|
||||
})
|
||||
.catch((error) => {
|
||||
rej(error.message || 'An error occurred');
|
||||
rej(error.message || 'An error occurred'); // TODO translate
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -105,7 +105,7 @@ export const ManageMembers = ({
|
||||
rej(response.error);
|
||||
})
|
||||
.catch((error) => {
|
||||
rej(error.message || 'An error occurred');
|
||||
rej(error.message || 'An error occurred'); // TODO translate
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -87,7 +87,7 @@ export const QMailMessages = ({ userName, userAddress }) => {
|
||||
rej(response.error);
|
||||
})
|
||||
.catch((error) => {
|
||||
rej(error.message || 'An error occurred');
|
||||
rej(error.message || 'An error occurred'); // TODO translate
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -79,7 +79,7 @@ export const Settings = ({ address, open, setOpen }) => {
|
||||
if (response?.error) {
|
||||
console.error('Error adding user settings:', response.error);
|
||||
} else {
|
||||
console.log('User settings added successfully');
|
||||
console.log('User settings added successfully'); // TODO translate
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -1,45 +1,57 @@
|
||||
import { Box, Button, ListItem, ListItemButton, ListItemText, Popover, Typography } from '@mui/material';
|
||||
import React, { useContext, useEffect, useRef, useState } from 'react'
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
|
||||
import {
|
||||
Box,
|
||||
ListItem,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Popover,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
List,
|
||||
} from 'react-virtualized';
|
||||
import { MyContext, getBaseApiReact } from '../../App';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { getBaseApi, getFee } from '../../background';
|
||||
import { getFee } from '../../background';
|
||||
import LockIcon from '@mui/icons-material/Lock';
|
||||
import NoEncryptionGmailerrorredIcon from '@mui/icons-material/NoEncryptionGmailerrorred';
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: 50,
|
||||
});
|
||||
|
||||
|
||||
|
||||
const getGroupInfo = async (groupId) => {
|
||||
const response = await fetch(`${getBaseApiReact()}/groups/` + groupId);
|
||||
const groupData = await response.json();
|
||||
|
||||
if (groupData) {
|
||||
return groupData
|
||||
}
|
||||
return groupData;
|
||||
}
|
||||
};
|
||||
export const getGroupNames = async (listOfGroups) => {
|
||||
let groups = [];
|
||||
if (listOfGroups && Array.isArray(listOfGroups)) {
|
||||
for (const group of listOfGroups) {
|
||||
|
||||
const groupInfo = await getGroupInfo(group.groupId);
|
||||
if (groupInfo) {
|
||||
groups.push({ ...group, ...groupInfo });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
};
|
||||
|
||||
export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
const {txList, setTxList, show} = useContext(MyContext)
|
||||
export const UserListOfInvites = ({
|
||||
myAddress,
|
||||
setInfoSnack,
|
||||
setOpenSnack,
|
||||
}) => {
|
||||
const { txList, setTxList, show } = useContext(MyContext);
|
||||
const [invites, setInvites] = useState<any[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@ -49,20 +61,20 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
|
||||
const getRequests = async () => {
|
||||
try {
|
||||
const response = await fetch(`${getBaseApiReact()}/groups/invites/${myAddress}/?limit=0`);
|
||||
const response = await fetch(
|
||||
`${getBaseApiReact()}/groups/invites/${myAddress}/?limit=0`
|
||||
);
|
||||
const inviteData = await response.json();
|
||||
|
||||
const resMoreData = await getGroupNames(inviteData)
|
||||
const resMoreData = await getGroupNames(inviteData);
|
||||
setInvites(resMoreData);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
getRequests();
|
||||
|
||||
}, []);
|
||||
|
||||
const handlePopoverOpen = (event, index) => {
|
||||
@ -77,17 +89,17 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
|
||||
const handleJoinGroup = async (groupId, groupName) => {
|
||||
try {
|
||||
|
||||
const fee = await getFee('JOIN_GROUP')
|
||||
const fee = await getFee('JOIN_GROUP'); // TODO translate
|
||||
await show({
|
||||
message: "Would you like to perform an JOIN_GROUP transaction?" ,
|
||||
publishFee: fee.fee + ' QORT'
|
||||
})
|
||||
message: 'Would you like to perform an JOIN_GROUP transaction?',
|
||||
publishFee: fee.fee + ' QORT',
|
||||
});
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("joinGroup", {
|
||||
window
|
||||
.sendMessage('joinGroup', {
|
||||
groupId,
|
||||
})
|
||||
.then((response) => {
|
||||
@ -105,15 +117,16 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
]);
|
||||
res(response);
|
||||
setInfoSnack({
|
||||
type: "success",
|
||||
message: "Successfully requested to join group. It may take a couple of minutes for the changes to propagate",
|
||||
type: 'success',
|
||||
message:
|
||||
'Successfully requested to join group. It may take a couple of minutes for the changes to propagate',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
handlePopoverClose();
|
||||
return;
|
||||
}
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
type: 'error',
|
||||
message: response?.error,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
@ -121,22 +134,18 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error.message || "An error occurred",
|
||||
type: 'error',
|
||||
message: error.message || 'An error occurred',
|
||||
});
|
||||
setOpenSnack(true);
|
||||
rej(error);
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const rowRenderer = ({ index, key, parent, style }) => {
|
||||
const invite = invites[index];
|
||||
@ -157,46 +166,61 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
anchorEl={popoverAnchor}
|
||||
onClose={handlePopoverClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
style={{ marginTop: "8px" }}
|
||||
style={{ marginTop: '8px' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "325px",
|
||||
height: "250px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
width: '325px',
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '10px',
|
||||
}}
|
||||
>
|
||||
<Typography>Join {invite?.groupName}</Typography>
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
loadingPosition="start"
|
||||
variant="contained" onClick={()=> handleJoinGroup(invite?.groupId, invite?.groupName)}>Join group</LoadingButton>
|
||||
variant="contained"
|
||||
onClick={() =>
|
||||
handleJoinGroup(invite?.groupId, invite?.groupName)
|
||||
}
|
||||
>
|
||||
Join group
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Popover>
|
||||
<ListItemButton onClick={(event) => handlePopoverOpen(event, index)}>
|
||||
<ListItemButton
|
||||
onClick={(event) => handlePopoverOpen(event, index)}
|
||||
>
|
||||
{invite?.isOpen === false && (
|
||||
<LockIcon sx={{
|
||||
color: 'var(--green)'
|
||||
}} />
|
||||
<LockIcon
|
||||
sx={{
|
||||
color: 'var(--green)',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{invite?.isOpen === true && (
|
||||
<NoEncryptionGmailerrorredIcon sx={{
|
||||
color: 'var(--danger)'
|
||||
}} />
|
||||
<NoEncryptionGmailerrorredIcon
|
||||
sx={{
|
||||
color: 'var(--danger)',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Spacer width="15px" />
|
||||
<ListItemText primary={invite?.groupName} secondary={invite?.description} />
|
||||
<ListItemText
|
||||
primary={invite?.groupName}
|
||||
secondary={invite?.description}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</div>
|
||||
@ -206,18 +230,20 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexGrow: 1
|
||||
}}>
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<p>Invite list</p>
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
@ -237,4 +263,4 @@ export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ export const WalletsAppWrapper = () => {
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<Typography>Q-Wallets</Typography>
|
||||
<Typography>Q-Wallets</Typography> // TODO translate
|
||||
<ButtonBase onClick={handleClose}>
|
||||
<CloseIcon
|
||||
sx={{
|
||||
|
@ -1,12 +1,16 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { getBaseApiReactSocket, pauseAllQueues, resumeAllQueues } from '../../App';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import {
|
||||
getBaseApiReactSocket,
|
||||
pauseAllQueues,
|
||||
resumeAllQueues,
|
||||
} from '../../App';
|
||||
import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
|
||||
|
||||
export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
||||
const socketRef = useRef(null); // WebSocket reference
|
||||
const timeoutIdRef = useRef(null); // Timeout ID reference
|
||||
const groupSocketTimeoutRef = useRef(null); // Group Socket Timeout reference
|
||||
const initiateRef = useRef(null)
|
||||
const initiateRef = useRef(null);
|
||||
const forceCloseWebSocket = () => {
|
||||
if (socketRef.current) {
|
||||
clearTimeout(timeoutIdRef.current);
|
||||
@ -17,21 +21,20 @@ export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
||||
};
|
||||
|
||||
const logoutEventFunc = () => {
|
||||
forceCloseWebSocket()
|
||||
forceCloseWebSocket();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
subscribeToEvent("logout-event", logoutEventFunc);
|
||||
subscribeToEvent('logout-event', logoutEventFunc);
|
||||
|
||||
return () => {
|
||||
unsubscribeFromEvent("logout-event", logoutEventFunc);
|
||||
unsubscribeFromEvent('logout-event', logoutEventFunc);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!myAddress) return; // Only proceed if myAddress is set
|
||||
|
||||
|
||||
const pingHeads = () => {
|
||||
try {
|
||||
if (socketRef.current?.readyState === WebSocket.OPEN) {
|
||||
@ -54,9 +57,8 @@ export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
||||
|
||||
try {
|
||||
if (!initiateRef.current) {
|
||||
setIsLoadingGroups(true)
|
||||
pauseAllQueues()
|
||||
|
||||
setIsLoadingGroups(true);
|
||||
pauseAllQueues();
|
||||
}
|
||||
const socketLink = `${getBaseApiReactSocket()}/websockets/chat/active/${currentAddress}?encoding=BASE64&haschatreference=false`;
|
||||
socketRef.current = new WebSocket(socketLink);
|
||||
@ -72,33 +74,45 @@ export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
||||
groupSocketTimeoutRef.current = setTimeout(pingHeads, 45000); // Ping every 45 seconds
|
||||
} else {
|
||||
if (!initiateRef.current) {
|
||||
setIsLoadingGroups(false)
|
||||
initiateRef.current = true
|
||||
resumeAllQueues()
|
||||
|
||||
setIsLoadingGroups(false);
|
||||
initiateRef.current = true;
|
||||
resumeAllQueues();
|
||||
}
|
||||
const data = JSON.parse(e.data);
|
||||
const copyGroups = [...(data?.groups || [])]
|
||||
const findIndex = copyGroups?.findIndex(item => item?.groupId === 0)
|
||||
const copyGroups = [...(data?.groups || [])];
|
||||
const findIndex = copyGroups?.findIndex(
|
||||
(item) => item?.groupId === 0
|
||||
);
|
||||
if (findIndex !== -1) {
|
||||
copyGroups[findIndex] = {
|
||||
...(copyGroups[findIndex] || {}),
|
||||
groupId: "0"
|
||||
groupId: '0',
|
||||
};
|
||||
}
|
||||
}
|
||||
const filteredGroups = copyGroups
|
||||
const sortedGroups = filteredGroups.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
||||
const sortedDirects = (data?.direct || []).filter(item =>
|
||||
item?.name !== 'extension-proxy' && item?.address !== 'QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH'
|
||||
).sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
||||
const filteredGroups = copyGroups;
|
||||
const sortedGroups = filteredGroups.sort(
|
||||
(a, b) => (b.timestamp || 0) - (a.timestamp || 0)
|
||||
);
|
||||
const sortedDirects = (data?.direct || [])
|
||||
.filter(
|
||||
(item) =>
|
||||
item?.name !== 'extension-proxy' &&
|
||||
item?.address !== 'QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH'
|
||||
)
|
||||
.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
||||
|
||||
window.sendMessage("handleActiveGroupDataFromSocket", {
|
||||
window
|
||||
.sendMessage('handleActiveGroupDataFromSocket', {
|
||||
groups: sortedGroups,
|
||||
directs: sortedDirects,
|
||||
}).catch((error) => {
|
||||
console.error("Failed to handle active group data from socket:", error.message || "An error occurred");
|
||||
})
|
||||
.catch((error) => {
|
||||
// TODO translate
|
||||
console.error(
|
||||
'Failed to handle active group data from socket:',
|
||||
error.message || 'An error occurred'
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing onmessage data:', error);
|
||||
@ -127,10 +141,8 @@ export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
initWebsocketMessageGroup(); // Initialize WebSocket on component mount
|
||||
|
||||
|
||||
return () => {
|
||||
forceCloseWebSocket(); // Clean up WebSocket on component unmount
|
||||
};
|
||||
|
@ -1,42 +1,34 @@
|
||||
import React, { useCallback, useEffect, useRef } from "react";
|
||||
import { getBaseApiReact } from "../../App";
|
||||
import { truncate } from "lodash";
|
||||
|
||||
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
export const useBlockedAddresses = () => {
|
||||
const userBlockedRef = useRef({})
|
||||
const userNamesBlockedRef = useRef({})
|
||||
const userBlockedRef = useRef({});
|
||||
const userNamesBlockedRef = useRef({});
|
||||
|
||||
const getAllBlockedUsers = useCallback(() => {
|
||||
|
||||
return {
|
||||
names: userNamesBlockedRef.current,
|
||||
addresses: userBlockedRef.current
|
||||
}
|
||||
}, [])
|
||||
addresses: userBlockedRef.current,
|
||||
};
|
||||
}, []);
|
||||
|
||||
const isUserBlocked = useCallback((address, name) => {
|
||||
try {
|
||||
if(!address) return false
|
||||
if(userBlockedRef.current[address]) return true
|
||||
return false
|
||||
|
||||
|
||||
if (!address) return false;
|
||||
if (userBlockedRef.current[address]) return true;
|
||||
return false;
|
||||
} catch (error) {
|
||||
//error
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlockedList = async () => {
|
||||
try {
|
||||
const response = await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'get',
|
||||
listName: `blockedAddresses`,
|
||||
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
@ -47,21 +39,20 @@ export const useBlockedAddresses = () => {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
})
|
||||
const blockedUsers = {}
|
||||
});
|
||||
const blockedUsers = {};
|
||||
response?.forEach((item) => {
|
||||
blockedUsers[item] = true
|
||||
})
|
||||
userBlockedRef.current = blockedUsers
|
||||
blockedUsers[item] = true;
|
||||
});
|
||||
userBlockedRef.current = blockedUsers;
|
||||
|
||||
const response2 = await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'get',
|
||||
listName: `blockedNames`,
|
||||
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
@ -72,147 +63,132 @@ export const useBlockedAddresses = () => {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
})
|
||||
const blockedUsers2 = {}
|
||||
});
|
||||
const blockedUsers2 = {};
|
||||
response2?.forEach((item) => {
|
||||
blockedUsers2[item] = true
|
||||
})
|
||||
userNamesBlockedRef.current = blockedUsers2
|
||||
|
||||
|
||||
blockedUsers2[item] = true;
|
||||
});
|
||||
userNamesBlockedRef.current = blockedUsers2;
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
fetchBlockedList()
|
||||
}, [])
|
||||
};
|
||||
fetchBlockedList();
|
||||
}, []);
|
||||
|
||||
const removeBlockFromList = useCallback(async (address, name) => {
|
||||
if (name) {
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'remove',
|
||||
items: [name],
|
||||
listName: 'blockedNames'
|
||||
|
||||
listName: 'blockedNames',
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
rej(response?.message);
|
||||
return;
|
||||
} else {
|
||||
|
||||
const copyObject = {...userNamesBlockedRef.current}
|
||||
delete copyObject[name]
|
||||
userNamesBlockedRef.current = copyObject
|
||||
|
||||
const copyObject = { ...userNamesBlockedRef.current };
|
||||
delete copyObject[name];
|
||||
userNamesBlockedRef.current = copyObject;
|
||||
|
||||
res(response);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
if (address) {
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'remove',
|
||||
items: [address],
|
||||
listName: 'blockedAddresses'
|
||||
|
||||
listName: 'blockedAddresses',
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
rej(response?.message);
|
||||
return;
|
||||
} else {
|
||||
|
||||
const copyObject = {...userBlockedRef.current}
|
||||
delete copyObject[address]
|
||||
userBlockedRef.current = copyObject
|
||||
|
||||
const copyObject = { ...userBlockedRef.current };
|
||||
delete copyObject[address];
|
||||
userBlockedRef.current = copyObject;
|
||||
|
||||
res(response);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
const addToBlockList = useCallback(async (address, name) => {
|
||||
if (name) {
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'add',
|
||||
items: [name],
|
||||
listName: 'blockedNames'
|
||||
|
||||
listName: 'blockedNames',
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
rej(response?.message);
|
||||
return;
|
||||
} else {
|
||||
const copyObject = {...userNamesBlockedRef.current}
|
||||
copyObject[name] = true
|
||||
userNamesBlockedRef.current = copyObject
|
||||
|
||||
const copyObject = { ...userNamesBlockedRef.current };
|
||||
copyObject[name] = true;
|
||||
userNamesBlockedRef.current = copyObject;
|
||||
|
||||
res(response);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
if (address) {
|
||||
await new Promise((res, rej) => {
|
||||
window.sendMessage("listActions", {
|
||||
|
||||
window
|
||||
.sendMessage('listActions', {
|
||||
type: 'add',
|
||||
items: [address],
|
||||
listName: 'blockedAddresses'
|
||||
|
||||
listName: 'blockedAddresses',
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.error) {
|
||||
rej(response?.message);
|
||||
return;
|
||||
} else {
|
||||
|
||||
const copyObject = {...userBlockedRef.current}
|
||||
copyObject[address] = true
|
||||
userBlockedRef.current = copyObject
|
||||
const copyObject = { ...userBlockedRef.current };
|
||||
copyObject[address] = true;
|
||||
userBlockedRef.current = copyObject;
|
||||
|
||||
res(response);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed qortalRequest", error);
|
||||
console.error('Failed qortalRequest', error);
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
return {
|
||||
isUserBlocked,
|
||||
addToBlockList,
|
||||
removeBlockFromList,
|
||||
getAllBlockedUsers
|
||||
getAllBlockedUsers,
|
||||
};
|
||||
};
|
||||
|
@ -1,32 +1,30 @@
|
||||
import React, { useCallback, useRef } from "react";
|
||||
import { getBaseApiReact } from "../../App";
|
||||
|
||||
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { getBaseApiReact } from '../../App';
|
||||
|
||||
export const useHandleUserInfo = () => {
|
||||
const userInfoRef = useRef({})
|
||||
|
||||
const userInfoRef = useRef({});
|
||||
|
||||
const getIndividualUserInfo = useCallback(async (address) => {
|
||||
try {
|
||||
if(!address) return null
|
||||
if(userInfoRef.current[address] !== undefined) return userInfoRef.current[address]
|
||||
if (!address) return null;
|
||||
if (userInfoRef.current[address] !== undefined)
|
||||
return userInfoRef.current[address];
|
||||
|
||||
const url = `${getBaseApiReact()}/addresses/${address}`;
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error("network error");
|
||||
throw new Error('network error');
|
||||
}
|
||||
const data = await response.json();
|
||||
userInfoRef.current = {
|
||||
...userInfoRef.current,
|
||||
[address]: data?.level
|
||||
}
|
||||
return data?.level
|
||||
[address]: data?.level,
|
||||
};
|
||||
return data?.level;
|
||||
} catch (error) {
|
||||
//error
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
return {
|
||||
getIndividualUserInfo,
|
||||
|
@ -1,40 +1,40 @@
|
||||
import { Box, ButtonBase, Typography } from "@mui/material";
|
||||
import React from "react";
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { Box, ButtonBase, Typography } from '@mui/material';
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
|
||||
export const NewUsersCTA = ({ balance }) => {
|
||||
if (balance === undefined || +balance > 0) return null;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Spacer height="40px" />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
width: "320px",
|
||||
justifyContent: "center",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
padding: "15px",
|
||||
outline: "1px solid gray",
|
||||
borderRadius: "4px",
|
||||
width: '320px',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
padding: '15px',
|
||||
outline: '1px solid gray',
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
fontSize: "1.2rem",
|
||||
fontWeight: "bold",
|
||||
textAlign: 'center',
|
||||
fontSize: '1.2rem',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Are you a new user?
|
||||
</Typography>
|
||||
</Typography>{' '}
|
||||
// TODO translate
|
||||
<Spacer height="20px" />
|
||||
<Typography>
|
||||
Please message us on Telegram or Discord if you need 4 QORT to start
|
||||
@ -43,25 +43,25 @@ export const NewUsersCTA = ({ balance }) => {
|
||||
<Spacer height="20px" />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
justifyContent: "center",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
gap: '10px',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
textDecoration: "underline",
|
||||
textDecoration: 'underline',
|
||||
}}
|
||||
onClick={() => {
|
||||
if (window?.electronAPI?.openExternal) {
|
||||
window.electronAPI.openExternal(
|
||||
"https://link.qortal.dev/telegram-invite"
|
||||
'https://link.qortal.dev/telegram-invite'
|
||||
);
|
||||
} else {
|
||||
window.open(
|
||||
"https://link.qortal.dev/telegram-invite",
|
||||
"_blank"
|
||||
'https://link.qortal.dev/telegram-invite',
|
||||
'_blank'
|
||||
);
|
||||
}
|
||||
}}
|
||||
@ -70,15 +70,15 @@ export const NewUsersCTA = ({ balance }) => {
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
textDecoration: "underline",
|
||||
textDecoration: 'underline',
|
||||
}}
|
||||
onClick={() => {
|
||||
if (window?.electronAPI?.openExternal) {
|
||||
window.electronAPI.openExternal(
|
||||
"https://link.qortal.dev/discord-invite"
|
||||
'https://link.qortal.dev/discord-invite'
|
||||
);
|
||||
} else {
|
||||
window.open("https://link.qortal.dev/discord-invite", "_blank");
|
||||
window.open('https://link.qortal.dev/discord-invite', '_blank');
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -206,7 +206,6 @@ export const Minting = ({
|
||||
window
|
||||
.sendMessage(
|
||||
'ADMIN_ACTION',
|
||||
|
||||
{
|
||||
type: 'addmintingaccount',
|
||||
value: val,
|
||||
@ -266,7 +265,7 @@ export const Minting = ({
|
||||
rej({ message: response.error });
|
||||
})
|
||||
.catch((error) => {
|
||||
rej({ message: error.message || 'An error occurred' });
|
||||
rej({ message: error.message || 'An error occurred' }); //TODO translate
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user