This commit is contained in:
PhilReact 2025-05-03 00:04:55 +03:00
parent c609fbb054
commit 138a21644f
5 changed files with 194 additions and 98 deletions

View File

@ -27,8 +27,12 @@ import {
DialogContent, DialogContent,
DialogContentText, DialogContentText,
DialogTitle, DialogTitle,
FormControl,
FormControlLabel, FormControlLabel,
FormLabel,
IconButton, IconButton,
Radio,
RadioGroup,
Snackbar, Snackbar,
SnackbarCloseReason, SnackbarCloseReason,
Tooltip, Tooltip,
@ -96,6 +100,7 @@ export const TradeOffers: React.FC<any> = ({
selectedCoin, selectedCoin,
} = useContext(gameContext); } = useContext(gameContext);
const isRemoveOrdersWithoutUnlockingFees = useRef(false); const isRemoveOrdersWithoutUnlockingFees = useRef(false);
const [isRemoveOrders, setIsRemoveOrders] = useState('remove');
const listOfOngoingTradesAts = useMemo(() => { const listOfOngoingTradesAts = useMemo(() => {
return ( return (
onGoingTrades onGoingTrades
@ -149,25 +154,14 @@ export const TradeOffers: React.FC<any> = ({
const feeRef = useRef(fee); const feeRef = useRef(fee);
const knownFees = useMemo(() => { const knownFees = useMemo(() => {
const offersWithKnownFees = [];
selectedOffers.forEach((offer) => {
const feeEntry = signedUnlockingFees.find(
(item) => item?.atAddress === offer.qortalAtAddress
);
if (feeEntry && typeof feeEntry.fee === "number") { const lengthOfOffers = selectedOffers.length
offersWithKnownFees.push({ ...offer, fee: feeEntry.fee }); const totalKnownFees = lengthOfOffers * fee
}
});
const totalKnownFees = offersWithKnownFees.reduce((sum, offer) => {
return sum + (offer.fee || 0);
}, 0);
const feeInLtc = totalKnownFees / 1e8; const feeInLtc = totalKnownFees / 1e8;
return +feeInLtc.toFixed(8); return +feeInLtc.toFixed(8);
}, [selectedOffers, signedUnlockingFees]); }, [selectedOffers, fee]);
console.log("knownFees", knownFees);
const defaultColDef = { const defaultColDef = {
resizable: true, // Make columns resizable by default resizable: true, // Make columns resizable by default
@ -175,6 +169,12 @@ export const TradeOffers: React.FC<any> = ({
suppressMovable: true, // Prevent columns from being movable suppressMovable: true, // Prevent columns from being movable
}; };
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const val = event.target.value
isRemoveOrdersWithoutUnlockingFees.current = val === 'remove' ? true : false
setIsRemoveOrders(val);
};
const getName = async (address) => { const getName = async (address) => {
try { try {
const response = await fetch("/names/address/" + address); const response = await fetch("/names/address/" + address);
@ -278,7 +278,6 @@ export const TradeOffers: React.FC<any> = ({
resizable: true, resizable: true,
valueGetter: (params) => { valueGetter: (params) => {
if (params?.data?.qortalAtAddress) { if (params?.data?.qortalAtAddress) {
console.log("22signedUnlockingFees", signedUnlockingFees);
const hasSignedFee = signedUnlockingFees?.find( const hasSignedFee = signedUnlockingFees?.find(
(item) => item?.atAddress === params.data.qortalAtAddress (item) => item?.atAddress === params.data.qortalAtAddress
); );
@ -570,7 +569,6 @@ export const TradeOffers: React.FC<any> = ({
} }
}, []); }, []);
console.log("signed", signedUnlockingFees);
useEffect(() => { useEffect(() => {
getSignedUnlockingFees(); getSignedUnlockingFees();
@ -602,54 +600,54 @@ export const TradeOffers: React.FC<any> = ({
const total = selectedOffers.reduce((acc: number, curr: any) => { const total = selectedOffers.reduce((acc: number, curr: any) => {
return acc + (+curr.foreignAmount || 0); // Ensure qortAmount is defined return acc + (+curr.foreignAmount || 0); // Ensure qortAmount is defined
}, 0); }, 0);
if (selectedCoin === "PIRATECHAIN") return total;
const totalWithKnownFees = +total + +knownFees; const totalWithKnownFees = +total + +knownFees;
return totalWithKnownFees; return totalWithKnownFees;
}, [selectedOffers, knownFees]); }, [selectedOffers, knownFees, selectedCoin]);
const buyOrder = async () => { const buyOrder = async () => {
try { try {
isRemoveOrdersWithoutUnlockingFees.current = false;
if (+foreignCoinBalance < +selectedTotalLTC.toFixed(4)) { // if (+foreignCoinBalance < +selectedTotalLTC.toFixed(4)) {
setOpen(true); // setOpen(true);
setInfo({ // setInfo({
type: "error", // type: "error",
message: `You don't have enough ${getCoinLabel()} or your balance was not retrieved`, // message: `You don't have enough ${getCoinLabel()} or your balance was not retrieved`,
}); // });
return; // return;
} // }
if (selectedOffers?.length < 1) return; if (selectedOffers?.length < 1) return;
let offersWithKnownFees = []; let offersWithKnownFees = [];
const offersWithUnknownFees = []; const offersWithUnknownFees = [];
if (selectedCoin !== "PIRATECHAIN") {
selectedOffers.forEach((offer) => {
const feeEntry = signedUnlockingFees.find(
(item) => item?.atAddress === offer.qortalAtAddress
);
selectedOffers.forEach((offer) => { if (feeEntry && typeof feeEntry.fee === "number") {
const feeEntry = signedUnlockingFees.find( offersWithKnownFees.push({ ...offer, fee: feeEntry.fee });
(item) => item?.atAddress === offer.qortalAtAddress } else {
); offersWithUnknownFees.push(offer);
}
if (feeEntry && typeof feeEntry.fee === "number") {
offersWithKnownFees.push({ ...offer, fee: feeEntry.fee });
} else {
offersWithUnknownFees.push(offer);
}
});
console.log("offersWithKnownFees", offersWithKnownFees);
console.log("offersWithUnknownFees", offersWithUnknownFees);
if (offersWithUnknownFees?.length > 0) {
await showTradesUnknownFee({
message: "",
}); });
if (offersWithUnknownFees?.length > 0) {
await showTradesUnknownFee({
message: "",
});
if (!isRemoveOrdersWithoutUnlockingFees.current) { if (!isRemoveOrdersWithoutUnlockingFees.current) {
offersWithKnownFees = [ offersWithKnownFees = [
...offersWithKnownFees, ...offersWithKnownFees,
...offersWithUnknownFees, ...offersWithUnknownFees,
]; ];
}
} }
} else {
offersWithKnownFees = selectedOffers;
} }
console.log("offersWithKnownFees", offersWithKnownFees);
setIsShowBuyInProgress({ status: "buying" }); setIsShowBuyInProgress({ status: "buying" });
@ -742,11 +740,9 @@ export const TradeOffers: React.FC<any> = ({
const hasSignedFee = signedUnlockingFees?.find( const hasSignedFee = signedUnlockingFees?.find(
(item) => item?.atAddress === params.data.qortalAtAddress (item) => item?.atAddress === params.data.qortalAtAddress
); );
console.log("hasSignedFee", hasSignedFee);
if (hasSignedFee) { if (hasSignedFee) {
console.log("fee2fee", fee);
if (fee && hasSignedFee?.fee > fee) { if (fee && hasSignedFee?.fee > fee) {
return { backgroundColor: "#ff6347" }; return { backgroundColor: "#FF0000" };
} }
} }
@ -811,7 +807,6 @@ export const TradeOffers: React.FC<any> = ({
feeRef.current = fee; feeRef.current = fee;
if (gridRef.current?.api) { if (gridRef.current?.api) {
console.log("Total rows:", gridRef.current.api.getDisplayedRowCount());
gridRef.current.api.forEachNode((rowNode: RowNode) => { gridRef.current.api.forEachNode((rowNode: RowNode) => {
const qortalAtAddress = rowNode.data?.qortalAtAddress; const qortalAtAddress = rowNode.data?.qortalAtAddress;
@ -829,8 +824,8 @@ export const TradeOffers: React.FC<any> = ({
gridRef.current.api.refreshCells({ force: true }); gridRef.current.api.refreshCells({ force: true });
} }
}, [signedUnlockingFees, fee]); }, [signedUnlockingFees, fee]);
console.log("signedUnlockingFees", signedUnlockingFees, fee); if (!signedUnlockingFees || (!fee && selectedCoin !== "PIRATECHAIN"))
if (!signedUnlockingFees || !fee) return null; return null;
return ( return (
<MainContainer> <MainContainer>
@ -863,11 +858,7 @@ export const TradeOffers: React.FC<any> = ({
(item) => item?.atAddress === params.data.qortalAtAddress (item) => item?.atAddress === params.data.qortalAtAddress
); );
if (!hasSignedFee) selectable = true; if (!hasSignedFee) selectable = true;
console.log(
"fee",
feeRef.current,
signedUnlockingFeesRef.current
);
if (hasSignedFee && hasSignedFee?.fee > feeRef.current) if (hasSignedFee && hasSignedFee?.fee > feeRef.current)
selectable = false; selectable = false;
return selectable; return selectable;
@ -924,7 +915,9 @@ export const TradeOffers: React.FC<any> = ({
style={{ style={{
marginLeft: "auto", marginLeft: "auto",
}} }}
>{`${getCoinLabel()} (with known fees)`}</span> >{`${getCoinLabel()} ${
selectedCoin !== "PIRATECHAIN" ? "with unlocking fees" : ""
}`}</span>
</Typography> </Typography>
</Box> </Box>
<Typography <Typography
@ -1026,37 +1019,49 @@ export const TradeOffers: React.FC<any> = ({
</DialogContentText> </DialogContentText>
<Spacer height="20px" /> <Spacer height="20px" />
<FormControlLabel <FormControl>
sx={{ <RadioGroup
margin: 0, aria-labelledby="demo-controlled-radio-buttons-group"
}} name="controlled-radio-buttons-group"
control={ value={isRemoveOrders}
<Checkbox onChange={handleChange}
onChange={(e) => >
(isRemoveOrdersWithoutUnlockingFees.current = <FormControlLabel
e.target.checked) value={"remove"}
control={
<Radio
sx={{
"&.Mui-checked": {
color: "white",
},
"& .MuiSvgIcon-root": {
color: "white",
},
}}
/>
} }
edge="start" label="Remove orders with unknown unlocking fees"
tabIndex={-1}
disableRipple
sx={{
"&.Mui-checked": {
color: "white",
},
"& .MuiSvgIcon-root": {
color: "white",
},
}}
/> />
} <FormControlLabel
label={ value={'keep'}
<Box sx={{ display: "flex", alignItems: "center" }}> control={
<Typography sx={{ fontSize: "14px" }}> <Radio
Remove orders with unknown unlocking fees sx={{
</Typography> "&.Mui-checked": {
</Box> color: "white",
} },
/> "& .MuiSvgIcon-root": {
color: "white",
},
}}
/>
}
label="Keep orders with unknown unlocking fees"
/>
</RadioGroup>
</FormControl>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button <Button

View File

@ -67,6 +67,7 @@ import { ReusableModal } from "../common/reusable-modal/ReusableModal";
import { NotificationContext } from "../../contexts/notificationContext"; import { NotificationContext } from "../../contexts/notificationContext";
import UnsignedFees from "../sell/UnsignedFees"; import UnsignedFees from "../sell/UnsignedFees";
import { FeeManager } from "../sell/FeeManager"; import { FeeManager } from "../sell/FeeManager";
import { Info } from "../sell/Info";
const checkIfLocal = async () => { const checkIfLocal = async () => {
try { try {
@ -504,6 +505,7 @@ export const Header = ({
<SelectRow coin="ARRR" /> <SelectRow coin="ARRR" />
</MenuItem> </MenuItem>
</Select> </Select>
<Info />
{!isUsingGateway && selectedCoin !== 'PIRATECHAIN' && ( {!isUsingGateway && selectedCoin !== 'PIRATECHAIN' && (
<> <>
<FeeManager selectedCoin={selectedCoin} fee={fee} <FeeManager selectedCoin={selectedCoin} fee={fee}

View File

@ -51,7 +51,6 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
const [openAlert, setOpenAlert] = useState(false); const [openAlert, setOpenAlert] = useState(false);
const [info, setInfo] = useState<any>(null); const [info, setInfo] = useState<any>(null);
const { getCoinLabel } = useContext(gameContext); const { getCoinLabel } = useContext(gameContext);
console.log("editFee", editFee);
const handleCloseAlert = ( const handleCloseAlert = (
event?: React.SyntheticEvent | Event, event?: React.SyntheticEvent | Event,
reason?: SnackbarCloseReason reason?: SnackbarCloseReason
@ -73,7 +72,6 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
if (!coin) { if (!coin) {
return; return;
} }
console.log("selectedCoin", coin);
// const coinRequest = coin.current.toLowerCase(); // const coinRequest = coin.current.toLowerCase();
const typeRequest = "feerequired"; const typeRequest = "feerequired";
@ -90,7 +88,6 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
setFee(response); setFee(response);
} }
console.log("response", response);
} catch (error) { } catch (error) {
setFee(""); setFee("");
console.error(error); console.error(error);
@ -99,7 +96,6 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
useEffect(() => { useEffect(() => {
establishUpdateFeeForm(coin); establishUpdateFeeForm(coin);
console.log("editFee or fetch changed");
}, [coin, establishUpdateFeeForm]); }, [coin, establishUpdateFeeForm]);
const recommendedFeeData = useMemo(() => { const recommendedFeeData = useMemo(() => {
@ -114,8 +110,9 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
}, [resource?.data]); }, [resource?.data]);
const recommendedFeeDisplay = useMemo(() => { const recommendedFeeDisplay = useMemo(() => {
if (!selectedCoin || !recommendedFeeData) return; if (!selectedCoin || !recommendedFeeData) return null;
const coin = getCoinLabel(selectedCoin)?.toUpperCase(); const coin = getCoinLabel(selectedCoin)?.toUpperCase();
if(!recommendedFeeData[coin]) return null
return recommendedFeeData[coin][recommendedFee]; return recommendedFeeData[coin][recommendedFee];
}, [recommendedFeeData, recommendedFee, selectedCoin]); }, [recommendedFeeData, recommendedFee, selectedCoin]);
@ -127,7 +124,6 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
if(recommendedFee !== 'custom'){ if(recommendedFee !== 'custom'){
feeToSave = calculateFeeFromRate(recommendedFeeDisplay, 300) feeToSave = calculateFeeFromRate(recommendedFeeDisplay, 300)
} }
console.log('feeToSave', feeToSave)
const response = await qortalRequestWithTimeout( const response = await qortalRequestWithTimeout(
{ {
action: "UPDATE_FOREIGN_FEE", action: "UPDATE_FOREIGN_FEE",
@ -205,7 +201,7 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
}, },
}} }}
> >
<Typography>Fee: {fee}</Typography> <Typography>Fee: {fee} sats</Typography>
<ChangeCircleIcon <ChangeCircleIcon
sx={{ sx={{

View File

@ -0,0 +1,94 @@
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from "react";
import gameContext from "../../contexts/gameContext";
import {
Alert,
Box,
ButtonBase,
Snackbar,
SnackbarCloseReason,
ToggleButton,
ToggleButtonGroup,
Typography,
} from "@mui/material";
import ChangeCircleIcon from "@mui/icons-material/ChangeCircle";
import { ReusableModal } from "../common/reusable-modal/ReusableModal";
import QuestionMarkIcon from "@mui/icons-material/QuestionMark";
import {
CoinActionContainer,
CoinActionRow,
HeaderRow,
} from "../header/Header-styles";
import { CustomInput, CustomLabel } from "./CreateSell";
import { Spacer } from "../common/Spacer";
import { usePublish, Service, QortalGetMetadata } from "qapp-core";
import { SetLeftFeature } from "ag-grid-community";
export const Info = () => {
const [openModal, setOpenModal] = useState(false)
return (
<>
<ButtonBase
onClick={() => {
setOpenModal(true);
}}
sx={{
minHeight: "42px",
border: "1px solid gray",
color: "white",
display: "flex",
alignItems: "center",
padding: "5px 5px",
gap: "10px",
borderRadius: "5px",
"&:hover": {
border: "1px solid white", // Border color on hover
},
}}
>
<QuestionMarkIcon
sx={{
color: "white",
}}
/>
</ButtonBase>
{openModal && (
<ReusableModal
onClickClose={() => {
setOpenModal(false);
}}
backdrop
>
<CoinActionContainer sx={{
width: '450px',
maxWidth: '95vw'
}}>
<CoinActionRow>
<HeaderRow>
<Typography
variant="h4"
sx={{
color: "white",
}}
>
Information on fees
</Typography>
</HeaderRow>
</CoinActionRow>
</CoinActionContainer>
</ReusableModal>
)}
</>
);
};

View File

@ -28,7 +28,6 @@ export default function UnsignedFees({ qortAddress }) {
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [openAlert, setOpenAlert] = useState(false); const [openAlert, setOpenAlert] = useState(false);
const [info, setInfo] = useState<any>(null); const [info, setInfo] = useState<any>(null);
console.log("isPositive", isPositive);
const qortAddressRef = useRef(null); const qortAddressRef = useRef(null);
const handleCloseAlert = ( const handleCloseAlert = (