2928 lines
84 KiB
TypeScript
Raw Normal View History

2024-09-09 20:36:39 +03:00
import {
createContext,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
2024-04-14 14:57:30 +03:00
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
import { useDropzone } from "react-dropzone";
2024-09-09 20:36:39 +03:00
import {
Box,
Button,
2024-09-24 17:09:13 +03:00
ButtonBase,
2024-09-09 20:36:39 +03:00
Checkbox,
CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Input,
InputLabel,
Popover,
Tooltip,
Typography,
} from "@mui/material";
2024-04-14 14:57:30 +03:00
import { decryptStoredWallet } from "./utils/decryptWallet";
import { CountdownCircleTimer } from "react-countdown-circle-timer";
2024-04-14 21:14:13 +03:00
import Logo1 from "./assets/svgs/Logo1.svg";
2024-04-15 22:30:49 +03:00
import Logo1Dark from "./assets/svgs/Logo1Dark.svg";
2024-09-09 20:36:39 +03:00
import RefreshIcon from "@mui/icons-material/Refresh";
2024-04-14 21:14:13 +03:00
import Logo2 from "./assets/svgs/Logo2.svg";
import Copy from "./assets/svgs/Copy.svg";
2024-09-09 20:36:39 +03:00
import ltcLogo from "./assets/ltc.png";
import qortLogo from "./assets/qort.png";
2024-04-14 21:14:13 +03:00
import { CopyToClipboard } from "react-copy-to-clipboard";
import Download from "./assets/svgs/Download.svg";
import Logout from "./assets/svgs/Logout.svg";
import Return from "./assets/svgs/Return.svg";
2024-04-14 23:01:28 +03:00
import Success from "./assets/svgs/Success.svg";
2024-04-15 22:30:49 +03:00
import Info from "./assets/svgs/Info.svg";
2024-10-15 17:48:03 +03:00
import CloseIcon from "@mui/icons-material/Close";
2024-09-12 05:01:36 +03:00
2024-04-14 14:57:30 +03:00
import {
createAccount,
generateRandomSentence,
saveFileToDisk,
} from "./utils/generateWallet/generateWallet";
import { kdf } from "./deps/kdf";
import { generateSaveWalletData } from "./utils/generateWallet/storeWallet";
import { crypto, walletVersion } from "./constants/decryptWallet";
import PhraseWallet from "./utils/generateWallet/phrase-wallet";
2024-04-14 21:14:13 +03:00
import {
AddressBox,
AppContainer,
AuthenticatedContainer,
AuthenticatedContainerInnerLeft,
AuthenticatedContainerInnerRight,
CustomButton,
CustomInput,
CustomLabel,
TextItalic,
TextP,
TextSpan,
} from "./App-styles";
import { Spacer } from "./common/Spacer";
2024-04-15 22:30:49 +03:00
import { Loader } from "./components/Loader";
import { PasswordField, ErrorText } from "./components";
2024-09-09 20:36:39 +03:00
import { ChatGroup } from "./components/Chat/ChatGroup";
2024-10-15 17:48:03 +03:00
import { Group, requestQueueMemberNames } from "./components/Group/Group";
2024-09-09 20:36:39 +03:00
import { TaskManger } from "./components/TaskManager/TaskManger";
import { useModal } from "./common/useModal";
import { LoadingButton } from "@mui/lab";
import { Label } from "./components/Group/AddGroup";
import { CustomizedSnackbars } from "./components/Snackbar/Snackbar";
2024-10-15 17:48:03 +03:00
import SettingsIcon from "@mui/icons-material/Settings";
2024-09-09 20:36:39 +03:00
import {
2024-10-24 03:55:10 +03:00
cleanUrl,
2024-09-09 20:36:39 +03:00
getFee,
2024-10-24 03:55:10 +03:00
getProtocol,
2024-09-09 20:36:39 +03:00
groupApi,
groupApiLocal,
groupApiSocket,
groupApiSocketLocal,
} from "./background";
2024-10-15 17:48:03 +03:00
import {
executeEvent,
subscribeToEvent,
unsubscribeFromEvent,
} from "./utils/events";
import {
requestQueueCommentCount,
requestQueuePublishedAccouncements,
} from "./components/Chat/GroupAnnouncements";
2024-09-09 20:36:39 +03:00
import { requestQueueGroupJoinRequests } from "./components/Group/GroupJoinRequests";
2024-09-12 05:01:36 +03:00
import { DrawerComponent } from "./components/Drawer/Drawer";
import { AddressQRCode } from "./components/AddressQRCode";
2024-09-24 17:09:13 +03:00
import { Settings } from "./components/Group/Settings";
2024-09-24 20:28:45 +03:00
import { MainAvatar } from "./components/MainAvatar";
2024-10-20 17:07:53 +03:00
import { useRetrieveDataLocalStorage } from "./useRetrieveDataLocalStorage";
2024-10-21 01:20:06 +03:00
import { useQortalGetSaveSettings } from "./useQortalGetSaveSettings";
2024-10-21 11:40:45 +03:00
import { useRecoilState, useResetRecoilState } from "recoil";
import { canSaveSettingToQdnAtom, fullScreenAtom, hasSettingsChangedAtom, oldPinnedAppsAtom, settingsLocalLastUpdatedAtom, settingsQDNLastUpdatedAtom, sortablePinnedAppsAtom } from "./atoms/global";
import { useAppFullScreen } from "./useAppFullscreen";
2024-10-23 17:52:30 +03:00
import { NotAuthenticated } from "./ExtStates/NotAuthenticated";
2024-04-14 14:57:30 +03:00
type extStates =
| "not-authenticated"
| "authenticated"
| "send-qort"
| "web-app-request-connection"
| "web-app-request-payment"
| "web-app-request-authentication"
| "download-wallet"
2024-04-15 22:30:49 +03:00
| "create-wallet"
| "transfer-success-regular"
2024-07-09 00:44:02 +03:00
| "transfer-success-request"
| "wallet-dropped"
2024-07-12 23:44:21 -04:00
| "web-app-request-buy-order"
2024-07-17 17:00:43 -04:00
| "buy-order-submitted"
2024-09-09 20:36:39 +03:00
| "group";
interface MyContextInterface {
txList: any[];
memberGroups: any[];
setTxList: (val) => void;
setMemberGroups: (val) => void;
isShow: boolean;
onCancel: () => void;
onOk: () => void;
show: () => void;
message: any;
}
const defaultValues: MyContextInterface = {
txList: [],
memberGroups: [],
setTxList: () => {},
setMemberGroups: () => {},
isShow: false,
onCancel: () => {},
onOk: () => {},
show: () => {},
message: {
publishFee: "",
message: "",
},
};
2024-10-25 12:38:47 +03:00
export let isMobile = false;
2024-09-12 05:01:36 +03:00
const isMobileDevice = () => {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
2024-10-15 17:48:03 +03:00
2024-09-12 05:01:36 +03:00
if (/android/i.test(userAgent)) {
return true; // Android device
}
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
return true; // iOS device
}
return false;
};
if (isMobileDevice()) {
2024-10-15 17:48:03 +03:00
isMobile = true;
2024-09-12 05:01:36 +03:00
console.log("Running on a mobile device");
} else {
console.log("Running on a desktop");
}
2024-09-09 20:36:39 +03:00
export const allQueues = {
requestQueueCommentCount: requestQueueCommentCount,
requestQueuePublishedAccouncements: requestQueuePublishedAccouncements,
requestQueueMemberNames: requestQueueMemberNames,
2024-10-15 17:48:03 +03:00
requestQueueGroupJoinRequests: requestQueueGroupJoinRequests,
};
2024-09-09 20:36:39 +03:00
const controlAllQueues = (action) => {
Object.keys(allQueues).forEach((key) => {
const val = allQueues[key];
try {
2024-10-15 17:48:03 +03:00
if (typeof val[action] === "function") {
2024-09-09 20:36:39 +03:00
val[action]();
}
} catch (error) {
console.error(error);
}
});
};
export const clearAllQueues = () => {
Object.keys(allQueues).forEach((key) => {
const val = allQueues[key];
try {
val.clear();
} catch (error) {
console.error(error);
}
});
2024-10-15 17:48:03 +03:00
};
2024-09-09 20:36:39 +03:00
export const pauseAllQueues = () => {
2024-10-15 17:48:03 +03:00
controlAllQueues("pause");
chrome?.runtime?.sendMessage({
action: "pauseAllQueues",
payload: {},
});
};
export const resumeAllQueues = () => {
2024-10-15 17:48:03 +03:00
controlAllQueues("resume");
chrome?.runtime?.sendMessage({
action: "resumeAllQueues",
payload: {},
});
};
2024-09-09 20:36:39 +03:00
export const MyContext = createContext<MyContextInterface>(defaultValues);
export let globalApiKey: string | null = null;
export const getBaseApiReact = (customApi?: string) => {
if (customApi) {
return customApi;
}
if (globalApiKey) {
2024-10-24 03:55:10 +03:00
return globalApiKey?.url;
2024-09-09 20:36:39 +03:00
} else {
return groupApi;
}
};
2024-09-16 12:35:43 +03:00
// export const getArbitraryEndpointReact = () => {
// if (globalApiKey) {
// return `/arbitrary/resources/search`;
// } else {
// return `/arbitrary/resources/searchsimple`;
// }
// };
export const getArbitraryEndpointReact = () => {
if (globalApiKey) {
2024-10-22 20:12:54 +03:00
return `/arbitrary/resources/searchsimple`;
2024-09-16 12:35:43 +03:00
} else {
return `/arbitrary/resources/searchsimple`;
}
};
2024-09-09 20:36:39 +03:00
export const getBaseApiReactSocket = (customApi?: string) => {
if (customApi) {
return customApi;
}
if (globalApiKey) {
2024-10-24 03:55:10 +03:00
return `${getProtocol(globalApiKey?.url) === 'http' ? 'ws://': 'wss://'}${cleanUrl(globalApiKey?.url)}`
2024-09-09 20:36:39 +03:00
} else {
return groupApiSocket;
}
};
export const isMainWindow = window?.location?.href?.includes("?main=true");
2024-04-14 14:57:30 +03:00
function App() {
const [extState, setExtstate] = useState<extStates>("not-authenticated");
2024-10-22 20:12:54 +03:00
const [desktopViewMode, setDesktopViewMode] = useState('home')
2024-04-14 14:57:30 +03:00
const [backupjson, setBackupjson] = useState<any>(null);
const [rawWallet, setRawWallet] = useState<any>(null);
2024-07-17 20:53:38 -04:00
const [ltcBalanceLoading, setLtcBalanceLoading] = useState<boolean>(false);
2024-09-09 20:36:39 +03:00
const [qortBalanceLoading, setQortBalanceLoading] = useState<boolean>(false);
2024-04-14 14:57:30 +03:00
const [decryptedWallet, setdecryptedWallet] = useState<any>(null);
const [requestConnection, setRequestConnection] = useState<any>(null);
2024-07-12 23:44:21 -04:00
const [requestBuyOrder, setRequestBuyOrder] = useState<any>(null);
2024-09-09 20:36:39 +03:00
const [authenticatedMode, setAuthenticatedMode] = useState("qort");
2024-04-14 14:57:30 +03:00
const [requestAuthentication, setRequestAuthentication] = useState<any>(null);
const [userInfo, setUserInfo] = useState<any>(null);
const [balance, setBalance] = useState<any>(null);
2024-09-09 20:36:39 +03:00
const [ltcBalance, setLtcBalance] = useState<any>(null);
2024-04-14 14:57:30 +03:00
const [paymentTo, setPaymentTo] = useState<string>("");
const [paymentAmount, setPaymentAmount] = useState<number>(0);
const [paymentPassword, setPaymentPassword] = useState<string>("");
const [sendPaymentError, setSendPaymentError] = useState<string>("");
const [sendPaymentSuccess, setSendPaymentSuccess] = useState<string>("");
const [countdown, setCountdown] = useState<null | number>(null);
const [walletToBeDownloaded, setWalletToBeDownloaded] = useState<any>(null);
const [walletToBeDownloadedPassword, setWalletToBeDownloadedPassword] =
useState<string>("");
2024-09-09 20:36:39 +03:00
const [isMain, setIsMain] = useState<boolean>(
window?.location?.href?.includes("?main=true")
);
const isMainRef = useRef(false);
const [authenticatePassword, setAuthenticatePassword] = useState<string>("");
2024-04-15 22:30:49 +03:00
const [sendqortState, setSendqortState] = useState<any>(null);
2024-09-09 20:36:39 +03:00
const [isLoading, setIsLoading] = useState<boolean>(false);
2024-04-14 21:14:13 +03:00
const [
walletToBeDownloadedPasswordConfirm,
setWalletToBeDownloadedPasswordConfirm,
] = useState<string>("");
2024-04-14 14:57:30 +03:00
const [walletToBeDownloadedError, setWalletToBeDownloadedError] =
useState<string>("");
2024-07-17 20:53:38 -04:00
const [walletToBeDecryptedError, setWalletToBeDecryptedError] =
2024-07-09 00:44:02 +03:00
useState<string>("");
2024-09-09 20:36:39 +03:00
const [txList, setTxList] = useState([]);
const [memberGroups, setMemberGroups] = useState([]);
const [isFocused, setIsFocused] = useState(true);
2024-10-21 11:40:45 +03:00
const [hasSettingsChanged, setHasSettingsChanged] = useRecoilState(hasSettingsChangedAtom)
2024-09-09 20:36:39 +03:00
const holdRefExtState = useRef<extStates>("not-authenticated");
const isFocusedRef = useRef<boolean>(true);
const { isShow, onCancel, onOk, show, message } = useModal();
2024-10-21 11:40:45 +03:00
const { isShow: isShowUnsavedChanges, onCancel: onCancelUnsavedChanges, onOk: onOkUnsavedChanges, show: showUnsavedChanges, message: messageUnsavedChanges } = useModal();
2024-10-15 17:48:03 +03:00
const {
onCancel: onCancelQortalRequest,
onOk: onOkQortalRequest,
show: showQortalRequest,
isShow: isShowQortalRequest,
message: messageQortalRequest,
} = useModal();
2024-10-21 11:40:45 +03:00
const {
onCancel: onCancelQortalRequestExtension,
onOk: onOkQortalRequestExtension,
show: showQortalRequestExtension,
isShow: isShowQortalRequestExtension,
message: messageQortalRequestExtension,
} = useModal();
2024-09-09 20:36:39 +03:00
const [openRegisterName, setOpenRegisterName] = useState(false);
const registerNamePopoverRef = useRef(null);
const [isLoadingRegisterName, setIsLoadingRegisterName] = useState(false);
const [registerNameValue, setRegisterNameValue] = useState("");
const [infoSnack, setInfoSnack] = useState(null);
const [openSnack, setOpenSnack] = useState(false);
const [hasLocalNode, setHasLocalNode] = useState(false);
2024-09-12 05:01:36 +03:00
const [isOpenDrawerProfile, setIsOpenDrawerProfile] = useState(false);
2024-09-09 20:36:39 +03:00
const [apiKey, setApiKey] = useState("");
2024-10-15 17:48:03 +03:00
const [isOpenSendQort, setIsOpenSendQort] = useState(false);
const [isOpenSendQortSuccess, setIsOpenSendQortSuccess] = useState(false);
const [rootHeight, setRootHeight] = useState("100%");
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
2024-10-14 23:27:11 +03:00
const qortalRequestCheckbox1Ref = useRef(null);
2024-10-20 17:07:53 +03:00
useRetrieveDataLocalStorage()
2024-10-21 01:20:06 +03:00
useQortalGetSaveSettings(userInfo?.name)
2024-10-21 11:40:45 +03:00
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
useEffect(() => {
// Attach a global event listener for double-click
const handleDoubleClick = () => {
toggleFullScreen();
};
2024-10-21 06:56:20 +03:00
2024-10-21 11:40:45 +03:00
// Add the event listener to the root HTML document
document.documentElement.addEventListener('dblclick', handleDoubleClick);
// Clean up the event listener on unmount
return () => {
document.documentElement.removeEventListener('dblclick', handleDoubleClick);
};
}, [toggleFullScreen]);
2024-10-21 06:56:20 +03:00
//resets for recoil
const resetAtomSortablePinnedAppsAtom = useResetRecoilState(sortablePinnedAppsAtom);
const resetAtomCanSaveSettingToQdnAtom = useResetRecoilState(canSaveSettingToQdnAtom);
const resetAtomSettingsQDNLastUpdatedAtom = useResetRecoilState(settingsQDNLastUpdatedAtom);
const resetAtomSettingsLocalLastUpdatedAtom = useResetRecoilState(settingsLocalLastUpdatedAtom);
const resetAtomOldPinnedAppsAtom = useResetRecoilState(oldPinnedAppsAtom);
const resetAllRecoil = () => {
resetAtomSortablePinnedAppsAtom();
resetAtomCanSaveSettingToQdnAtom();
resetAtomSettingsQDNLastUpdatedAtom();
resetAtomSettingsLocalLastUpdatedAtom();
resetAtomOldPinnedAppsAtom();
};
2024-09-09 20:36:39 +03:00
useEffect(() => {
2024-10-15 17:48:03 +03:00
if (!isMobile) return;
2024-09-12 05:01:36 +03:00
// Function to set the height of the app to the viewport height
const resetHeight = () => {
2024-10-15 17:48:03 +03:00
const height = window.visualViewport
? window.visualViewport.height
: window.innerHeight;
2024-09-12 05:01:36 +03:00
// Set the height to the root element (usually #root)
2024-10-15 17:48:03 +03:00
document.getElementById("root").style.height = height + "px";
setRootHeight(height + "px");
2024-09-12 05:01:36 +03:00
};
// Set the initial height
resetHeight();
// Add event listeners for resize and visualViewport changes
2024-10-15 17:48:03 +03:00
window.addEventListener("resize", resetHeight);
window.visualViewport?.addEventListener("resize", resetHeight);
2024-09-12 05:01:36 +03:00
// Clean up the event listeners when the component unmounts
return () => {
2024-10-15 17:48:03 +03:00
window.removeEventListener("resize", resetHeight);
window.visualViewport?.removeEventListener("resize", resetHeight);
2024-09-12 05:01:36 +03:00
};
}, []);
2024-10-23 17:52:30 +03:00
const handleSetGlobalApikey = (key)=> {
globalApiKey = key;
}
2024-09-12 05:01:36 +03:00
useEffect(() => {
chrome?.runtime?.sendMessage({ action: "getApiKey" }, (response) => {
2024-09-09 20:36:39 +03:00
if (response) {
2024-10-23 17:52:30 +03:00
handleSetGlobalApikey(response)
2024-09-09 20:36:39 +03:00
setApiKey(response);
2024-10-24 03:55:10 +03:00
2024-09-09 20:36:39 +03:00
}
});
}, []);
2024-07-17 20:53:38 -04:00
useEffect(() => {
if (extState) {
2024-09-09 20:36:39 +03:00
holdRefExtState.current = extState;
2024-04-25 12:48:26 +03:00
}
2024-09-09 20:36:39 +03:00
}, [extState]);
2024-04-25 12:48:26 +03:00
2024-09-09 20:36:39 +03:00
useEffect(() => {
isFocusedRef.current = isFocused;
}, [isFocused]);
2024-10-24 03:55:10 +03:00
2024-10-15 17:48:03 +03:00
2024-09-14 06:33:41 +03:00
// const checkIfUserHasLocalNode = useCallback(async () => {
// try {
// const url = `http://127.0.0.1:12391/admin/status`;
// const response = await fetch(url, {
// method: "GET",
// headers: {
// "Content-Type": "application/json",
// },
// });
// const data = await response.json();
// if (data?.isSynchronizing === false && data?.syncPercent === 100) {
// setHasLocalNode(true);
// }
// } catch (error) {}
// }, []);
// useEffect(() => {
// checkIfUserHasLocalNode();
// }, [extState]);
2024-07-18 12:26:13 -04:00
2024-04-14 14:57:30 +03:00
const address = useMemo(() => {
if (!rawWallet?.address0) return "";
return rawWallet.address0;
}, [rawWallet]);
const { getRootProps, getInputProps } = useDropzone({
accept: {
"application/json": [".json"], // Only accept JSON files
},
maxFiles: 1,
onDrop: async (acceptedFiles) => {
const file: any = acceptedFiles[0];
const fileContents = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onabort = () => reject("File reading was aborted");
reader.onerror = () => reject("File reading has failed");
reader.onload = () => {
// Resolve the promise with the reader result when reading completes
resolve(reader.result);
};
// Read the file as text
reader.readAsText(file);
});
2024-07-17 20:53:38 -04:00
2024-04-14 14:57:30 +03:00
let error: any = null;
let pf: any;
try {
if (typeof fileContents !== "string") return;
pf = JSON.parse(fileContents);
2024-09-09 20:36:39 +03:00
} catch (e) {}
2024-04-14 14:57:30 +03:00
try {
const requiredFields = [
"address0",
"salt",
"iv",
"version",
"encryptedSeed",
"mac",
"kdfThreads",
];
for (const field of requiredFields) {
if (!(field in pf)) throw new Error(field + " not found in JSON");
}
2024-07-09 00:44:02 +03:00
// storeWalletInfo(pf);
2024-04-14 14:57:30 +03:00
setRawWallet(pf);
2024-07-09 00:44:02 +03:00
// setExtstate("authenticated");
setExtstate("wallet-dropped");
2024-04-14 14:57:30 +03:00
setdecryptedWallet(null);
} catch (e) {
console.log(e);
error = e;
}
},
});
const saveWalletFunc = async (password: string) => {
let wallet = structuredClone(rawWallet);
2024-04-14 21:14:13 +03:00
const res = await decryptStoredWallet(password, wallet);
const wallet2 = new PhraseWallet(res, walletVersion);
wallet = await wallet2.generateSaveWalletData(
password,
crypto.kdfThreads,
2024-09-09 20:36:39 +03:00
() => {}
2024-04-14 21:14:13 +03:00
);
2024-04-14 14:57:30 +03:00
setWalletToBeDownloaded({
wallet,
qortAddress: rawWallet.address0,
});
return {
wallet,
qortAddress: rawWallet.address0,
};
};
const storeWalletInfo = (wallet: any) => {
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-04-14 14:57:30 +03:00
{ action: "storeWalletInfo", wallet },
(response) => {
if (response) {
}
}
);
chrome.tabs.query(
{ active: true, currentWindow: true },
function (tabs: any[]) {
chrome.tabs.sendMessage(
tabs[0].id,
{ from: "popup", subject: "anySubject" },
2024-09-09 20:36:39 +03:00
function (response) {}
2024-04-14 14:57:30 +03:00
);
}
);
};
2024-07-17 20:53:38 -04:00
2024-04-14 14:57:30 +03:00
const getBalanceFunc = () => {
2024-09-09 20:36:39 +03:00
setQortBalanceLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "balance" }, (response) => {
2024-07-18 12:26:13 -04:00
if (!response?.error && !isNaN(+response)) {
2024-04-14 14:57:30 +03:00
setBalance(response);
}
2024-09-09 20:36:39 +03:00
setQortBalanceLoading(false);
2024-07-17 20:53:38 -04:00
});
};
const getLtcBalanceFunc = () => {
2024-09-09 20:36:39 +03:00
setLtcBalanceLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "ltcBalance" }, (response) => {
2024-07-18 12:26:13 -04:00
if (!response?.error && !isNaN(+response)) {
2024-07-17 20:53:38 -04:00
setLtcBalance(response);
}
2024-09-09 20:36:39 +03:00
setLtcBalanceLoading(false);
2024-04-14 14:57:30 +03:00
});
};
const sendCoinFunc = () => {
setSendPaymentError("");
setSendPaymentSuccess("");
if (!paymentTo) {
setSendPaymentError("Please enter a recipient");
return;
}
if (!paymentAmount) {
setSendPaymentError("Please enter an amount greater than 0");
return;
}
if (!paymentPassword) {
setSendPaymentError("Please enter your wallet password");
return;
}
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-04-14 14:57:30 +03:00
{
action: "sendCoin",
payload: {
amount: Number(paymentAmount),
receiver: paymentTo.trim(),
password: paymentPassword,
},
},
(response) => {
if (response?.error) {
setSendPaymentError(response.error);
} else {
2024-10-15 17:48:03 +03:00
setIsOpenSendQort(false);
setIsOpenSendQortSuccess(true);
// setExtstate("transfer-success-regular");
2024-04-15 22:30:49 +03:00
// setSendPaymentSuccess("Payment successfully sent");
2024-04-14 14:57:30 +03:00
}
2024-09-09 20:36:39 +03:00
setIsLoading(false);
2024-04-14 14:57:30 +03:00
}
);
};
const clearAllStates = () => {
setRequestConnection(null);
setRequestAuthentication(null);
};
2024-10-15 17:48:03 +03:00
const qortalRequestPermisson = async (message, sender, sendResponse) => {
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
2024-10-14 18:59:42 +03:00
try {
2024-10-15 17:48:03 +03:00
await showQortalRequest(message?.payload);
2024-10-27 15:56:26 +02:00
if (qortalRequestCheckbox1Ref.current) {
2024-10-21 11:40:45 +03:00
2024-10-15 17:48:03 +03:00
sendResponse({
accepted: true,
checkbox1: qortalRequestCheckbox1Ref.current,
});
return;
2024-10-14 23:27:11 +03:00
}
2024-10-15 17:48:03 +03:00
sendResponse({ accepted: true });
2024-10-14 18:59:42 +03:00
} catch (error) {
2024-10-15 17:48:03 +03:00
sendResponse({ accepted: false });
2024-10-14 18:59:42 +03:00
} finally {
window.close();
}
}
2024-10-15 17:48:03 +03:00
};
2024-10-21 06:56:20 +03:00
const qortalRequestPermissonFromExtension = async (message, sender, sendResponse) => {
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow) {
try {
2024-11-12 21:06:16 +02:00
if(message?.payload?.checkbox1){
2024-11-13 05:05:40 +02:00
qortalRequestCheckbox1Ref.current = message?.payload?.checkbox1?.value || false
2024-11-12 21:06:16 +02:00
}
2024-10-21 11:40:45 +03:00
await showQortalRequestExtension(message?.payload);
2024-10-21 06:56:20 +03:00
2024-10-27 15:56:26 +02:00
if (qortalRequestCheckbox1Ref.current) {
sendResponse({
accepted: true,
checkbox1: qortalRequestCheckbox1Ref.current,
});
return;
}
2024-10-21 06:56:20 +03:00
sendResponse({ accepted: true });
} catch (error) {
sendResponse({ accepted: false });
}
}
};
2024-10-14 18:59:42 +03:00
2024-04-14 14:57:30 +03:00
useEffect(() => {
// Listen for messages from the background script
2024-10-14 18:59:42 +03:00
const messageListener = (message, sender, sendResponse) => {
// Handle various actions
2024-10-15 17:48:03 +03:00
if (
message.action === "UPDATE_STATE_CONFIRM_SEND_QORT" &&
!isMainWindow
) {
2024-04-14 14:57:30 +03:00
setSendqortState(message.payload);
setExtstate("web-app-request-payment");
2024-09-09 20:36:39 +03:00
} else if (message.action === "closePopup" && !isMainWindow) {
2024-04-14 14:57:30 +03:00
window.close();
2024-10-15 17:48:03 +03:00
} else if (
message.action === "UPDATE_STATE_REQUEST_CONNECTION" &&
!isMainWindow
) {
2024-04-14 14:57:30 +03:00
setRequestConnection(message.payload);
setExtstate("web-app-request-connection");
2024-10-15 17:48:03 +03:00
} else if (
message.action === "UPDATE_STATE_REQUEST_BUY_ORDER" &&
!isMainWindow
) {
2024-07-12 23:44:21 -04:00
setRequestBuyOrder(message.payload);
setExtstate("web-app-request-buy-order");
2024-10-15 17:48:03 +03:00
} else if (
message.action === "UPDATE_STATE_REQUEST_AUTHENTICATION" &&
!isMainWindow
) {
2024-04-14 14:57:30 +03:00
setRequestAuthentication(message.payload);
setExtstate("web-app-request-authentication");
2024-09-09 20:36:39 +03:00
} else if (message.action === "SET_COUNTDOWN" && !isMainWindow) {
2024-04-14 14:57:30 +03:00
setCountdown(message.payload);
2024-09-09 20:36:39 +03:00
} else if (message.action === "INITIATE_MAIN") {
setIsMain(true);
isMainRef.current = true;
} else if (message.action === "CHECK_FOCUS" && isMainWindow) {
2024-10-15 17:48:03 +03:00
sendResponse(isFocusedRef.current); // Synchronous response
return true; // Return true if you plan to send a response asynchronously
} else if (
message.action === "NOTIFICATION_OPEN_DIRECT" &&
isMainWindow
) {
2024-09-09 20:36:39 +03:00
executeEvent("openDirectMessage", {
from: message.payload.from,
});
} else if (message.action === "NOTIFICATION_OPEN_GROUP" && isMainWindow) {
executeEvent("openGroupMessage", {
from: message.payload.from,
});
2024-10-15 17:48:03 +03:00
} else if (
message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP" &&
isMainWindow
) {
2024-09-09 20:36:39 +03:00
executeEvent("openGroupAnnouncement", {
from: message.payload.from,
});
2024-10-15 17:48:03 +03:00
} else if (
message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST" &&
isMainWindow
) {
2024-09-09 20:36:39 +03:00
executeEvent("openThreadNewPost", {
data: message.payload.data,
});
2024-04-14 14:57:30 +03:00
}
2024-10-15 17:48:03 +03:00
2024-10-14 18:59:42 +03:00
// Call the permission request handler for "QORTAL_REQUEST_PERMISSION"
2024-10-15 17:48:03 +03:00
qortalRequestPermisson(message, sender, sendResponse);
2024-10-14 18:59:42 +03:00
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
2024-10-15 17:48:03 +03:00
return true; // Return true to indicate an async response is coming
}
2024-10-21 06:56:20 +03:00
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow && message?.isFromExtension) {
qortalRequestPermissonFromExtension(message, sender, sendResponse);
return true;
}
2024-10-15 17:48:03 +03:00
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow) {
2024-10-21 06:56:20 +03:00
2024-10-14 18:59:42 +03:00
return;
}
};
2024-10-15 17:48:03 +03:00
2024-10-14 18:59:42 +03:00
// Add message listener
chrome.runtime?.onMessage.addListener(messageListener);
2024-10-15 17:48:03 +03:00
2024-10-14 18:59:42 +03:00
// Clean up the listener on component unmount
return () => {
chrome.runtime?.onMessage.removeListener(messageListener);
};
2024-04-14 21:14:13 +03:00
}, []);
2024-04-14 14:57:30 +03:00
//param = isDecline
const confirmPayment = (isDecline: boolean) => {
if (isDecline) {
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-04-14 14:57:30 +03:00
{
action: "sendQortConfirmation",
payload: {
amount: sendqortState?.amount,
receiver: sendqortState?.address,
password: paymentPassword,
interactionId: sendqortState?.interactionId,
isDecline: true,
},
},
(response) => {
if (response) {
setSendPaymentSuccess("Payment successfully sent");
} else {
window.close();
}
}
);
return;
}
2024-07-12 23:44:21 -04:00
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-04-14 14:57:30 +03:00
{
action: "sendQortConfirmation",
payload: {
amount: sendqortState.amount,
receiver: sendqortState.address,
password: paymentPassword,
interactionId: sendqortState.interactionId,
isDecline: false,
},
},
(response) => {
2024-04-15 22:30:49 +03:00
if (response === true) {
setExtstate("transfer-success-request");
setCountdown(null);
2024-07-12 23:44:21 -04:00
} else {
setSendPaymentError(
response?.error || "Unable to perform payment. Please try again."
);
}
2024-09-09 20:36:39 +03:00
setIsLoading(false);
2024-07-12 23:44:21 -04:00
}
);
};
const confirmBuyOrder = (isDecline: boolean) => {
if (isDecline) {
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-07-12 23:44:21 -04:00
{
action: "buyOrderConfirmation",
payload: {
crosschainAtInfo: requestBuyOrder?.crosschainAtInfo,
interactionId: requestBuyOrder?.interactionId,
isDecline: true,
2024-10-15 17:48:03 +03:00
useLocal: requestBuyOrder?.useLocal,
2024-07-12 23:44:21 -04:00
},
},
(response) => {
2024-07-17 20:53:38 -04:00
window.close();
2024-07-12 23:44:21 -04:00
}
);
return;
}
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-07-12 23:44:21 -04:00
{
action: "buyOrderConfirmation",
payload: {
crosschainAtInfo: requestBuyOrder?.crosschainAtInfo,
2024-07-17 20:53:38 -04:00
interactionId: requestBuyOrder?.interactionId,
isDecline: false,
2024-10-15 17:48:03 +03:00
useLocal: requestBuyOrder?.useLocal,
2024-07-12 23:44:21 -04:00
},
},
(response) => {
if (response === true) {
2024-07-17 17:00:43 -04:00
setExtstate("buy-order-submitted");
2024-07-12 23:44:21 -04:00
setCountdown(null);
2024-04-15 22:30:49 +03:00
} else {
setSendPaymentError(
response?.error || "Unable to perform payment. Please try again."
);
2024-04-14 14:57:30 +03:00
}
2024-09-09 20:36:39 +03:00
setIsLoading(false);
2024-04-14 14:57:30 +03:00
}
);
};
const responseToConnectionRequest = (
isOkay: boolean,
hostname: string,
interactionId: string
) => {
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-04-14 14:57:30 +03:00
{
action: "responseToConnectionRequest",
payload: { isOkay, hostname, interactionId },
},
(response) => {
if (response === false || response === true) {
window.close();
}
}
);
};
2024-04-14 23:01:28 +03:00
// const rawWalletRef = useRef(null)
// useEffect(()=> {
// rawWalletRef.current = rawWallet
// }, [rawWallet])
2024-07-17 20:53:38 -04:00
2024-04-14 14:57:30 +03:00
useEffect(() => {
try {
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "getWalletInfo" }, (response) => {
2024-04-14 14:57:30 +03:00
if (response && response?.walletInfo) {
setRawWallet(response?.walletInfo);
2024-09-09 20:36:39 +03:00
if (
holdRefExtState.current === "web-app-request-payment" ||
holdRefExtState.current === "web-app-request-connection" ||
holdRefExtState.current === "web-app-request-buy-order"
)
return;
2024-04-14 14:57:30 +03:00
setExtstate("authenticated");
}
});
2024-09-09 20:36:39 +03:00
} catch (error) {
} finally {
setIsLoading(false);
2024-04-16 13:25:36 +03:00
}
2024-04-14 23:01:28 +03:00
}, []);
2024-04-14 14:57:30 +03:00
2024-09-09 20:36:39 +03:00
const getUserInfo = useCallback(async (useTimer?: boolean) => {
2024-04-14 14:57:30 +03:00
try {
2024-09-09 20:36:39 +03:00
if (useTimer) {
await new Promise((res) => {
setTimeout(() => {
res(null);
}, 10000);
});
}
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "userInfo" }, (response) => {
2024-04-14 14:57:30 +03:00
if (response && !response.error) {
setUserInfo(response);
}
});
getBalanceFunc();
2024-09-09 20:36:39 +03:00
} catch (error) {}
}, []);
useEffect(() => {
if (!address) return;
getUserInfo();
2024-04-14 14:57:30 +03:00
}, [address]);
useEffect(() => {
return () => {
console.log("exit");
};
}, []);
2024-09-09 20:36:39 +03:00
useEffect(() => {
if (
authenticatedMode === "ltc" &&
!ltcBalanceLoading &&
ltcBalance === null
) {
getLtcBalanceFunc();
2024-07-18 11:22:51 -04:00
}
2024-09-09 20:36:39 +03:00
}, [authenticatedMode]);
2024-07-18 11:22:51 -04:00
2024-04-14 14:57:30 +03:00
const confirmPasswordToDownload = async () => {
try {
setWalletToBeDownloadedError("");
if (!walletToBeDownloadedPassword) {
setSendPaymentError("Please enter your password");
return;
}
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-07-17 20:53:38 -04:00
await new Promise<void>((res) => {
setTimeout(() => {
2024-09-09 20:36:39 +03:00
res();
}, 250);
});
2024-04-14 14:57:30 +03:00
const res = await saveWalletFunc(walletToBeDownloadedPassword);
} catch (error: any) {
setWalletToBeDownloadedError(error?.message);
2024-04-15 22:30:49 +03:00
} finally {
2024-09-09 20:36:39 +03:00
setIsLoading(false);
2024-04-14 14:57:30 +03:00
}
};
const saveFileToDiskFunc = async () => {
try {
await saveFileToDisk(
walletToBeDownloaded.wallet,
walletToBeDownloaded.qortAddress
);
} catch (error: any) {
setWalletToBeDownloadedError(error?.message);
2024-04-15 22:30:49 +03:00
} finally {
2024-04-14 14:57:30 +03:00
}
};
const createAccountFunc = async () => {
try {
if (!walletToBeDownloadedPassword) {
setWalletToBeDownloadedError("Please enter a password");
return;
}
if (!walletToBeDownloadedPasswordConfirm) {
setWalletToBeDownloadedError("Please confirm your password");
return;
}
2024-04-14 21:14:13 +03:00
if (
walletToBeDownloadedPasswordConfirm !== walletToBeDownloadedPassword
) {
2024-04-14 14:57:30 +03:00
setWalletToBeDownloadedError("Password fields do not match!");
return;
}
2024-09-09 20:36:39 +03:00
setIsLoading(true);
2024-07-17 20:53:38 -04:00
await new Promise<void>((res) => {
setTimeout(() => {
2024-09-09 20:36:39 +03:00
res();
}, 250);
});
2024-04-14 21:14:13 +03:00
const res = await createAccount();
const wallet = await res.generateSaveWalletData(
walletToBeDownloadedPassword,
crypto.kdfThreads,
2024-09-09 20:36:39 +03:00
() => {}
2024-04-14 21:14:13 +03:00
);
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-09-09 20:36:39 +03:00
{
action: "decryptWallet",
payload: {
password: walletToBeDownloadedPassword,
2024-07-09 00:44:02 +03:00
wallet,
2024-09-09 20:36:39 +03:00
},
},
(response) => {
if (response && !response?.error) {
setRawWallet(wallet);
setWalletToBeDownloaded({
wallet,
qortAddress: wallet.address0,
});
2024-10-15 17:48:03 +03:00
chrome?.runtime?.sendMessage(
{ action: "userInfo" },
(response2) => {
setIsLoading(false);
if (response2 && !response2.error) {
setUserInfo(response);
}
2024-09-09 20:36:39 +03:00
}
2024-10-15 17:48:03 +03:00
);
2024-09-09 20:36:39 +03:00
getBalanceFunc();
} else if (response?.error) {
setIsLoading(false);
setWalletToBeDecryptedError(response.error);
}
2024-07-09 00:44:02 +03:00
}
2024-09-09 20:36:39 +03:00
);
2024-04-14 14:57:30 +03:00
} catch (error: any) {
setWalletToBeDownloadedError(error?.message);
2024-09-09 20:36:39 +03:00
setIsLoading(false);
2024-07-17 20:53:38 -04:00
}
2024-04-14 14:57:30 +03:00
};
2024-10-21 11:40:45 +03:00
const logoutFunc = async () => {
2024-04-14 14:57:30 +03:00
try {
2024-10-21 11:40:45 +03:00
if(hasSettingsChanged){
await showUnsavedChanges({message: 'Your settings have changed. If you logout you will lose your changes. Click on the save button in the header to keep your changed settings.'})
}
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "logout" }, (response) => {
2024-04-14 14:57:30 +03:00
if (response) {
2024-09-10 01:01:40 +03:00
executeEvent("logout-event", {});
2024-11-10 19:59:15 +02:00
resetAllStates();
2024-04-14 14:57:30 +03:00
}
});
2024-09-09 20:36:39 +03:00
} catch (error) {}
2024-04-14 21:14:13 +03:00
};
2024-04-14 23:01:28 +03:00
const returnToMain = () => {
2024-04-14 21:14:13 +03:00
setPaymentTo("");
setPaymentAmount(0);
setPaymentPassword("");
setSendPaymentError("");
setSendPaymentSuccess("");
setCountdown(null);
setWalletToBeDownloaded(null);
setWalletToBeDownloadedPassword("");
2024-04-14 23:01:28 +03:00
setExtstate("authenticated");
2024-10-15 17:48:03 +03:00
setIsOpenSendQort(false);
setIsOpenSendQortSuccess(false);
2024-04-14 23:01:28 +03:00
};
2024-04-15 22:30:49 +03:00
const resetAllStates = () => {
setExtstate("not-authenticated");
2024-09-09 20:36:39 +03:00
setAuthenticatedMode("qort");
2024-04-15 22:30:49 +03:00
setBackupjson(null);
setRawWallet(null);
setdecryptedWallet(null);
setRequestConnection(null);
2024-09-09 20:36:39 +03:00
setRequestBuyOrder(null);
2024-04-15 22:30:49 +03:00
setRequestAuthentication(null);
setUserInfo(null);
setBalance(null);
2024-09-09 20:36:39 +03:00
setLtcBalance(null);
2024-04-15 22:30:49 +03:00
setPaymentTo("");
setPaymentAmount(0);
setPaymentPassword("");
setSendPaymentError("");
setSendPaymentSuccess("");
setCountdown(null);
setWalletToBeDownloaded(null);
setWalletToBeDownloadedPassword("");
setWalletToBeDownloadedPasswordConfirm("");
setWalletToBeDownloadedError("");
setSendqortState(null);
2024-09-09 20:36:39 +03:00
setHasLocalNode(false);
2024-10-15 17:48:03 +03:00
setTxList([]);
setMemberGroups([]);
2024-10-21 06:56:20 +03:00
resetAllRecoil()
2024-04-15 22:30:49 +03:00
};
2024-11-12 21:06:16 +02:00
function roundUpToDecimals(number, decimals = 8) {
2024-09-18 00:08:19 +03:00
const factor = Math.pow(10, decimals); // Create a factor based on the number of decimals
return Math.ceil(+number * factor) / factor;
}
2024-07-17 20:53:38 -04:00
const authenticateWallet = async () => {
2024-07-09 00:44:02 +03:00
try {
2024-09-09 20:36:39 +03:00
setIsLoading(true);
setWalletToBeDecryptedError("");
2024-07-17 20:53:38 -04:00
await new Promise<void>((res) => {
setTimeout(() => {
2024-09-09 20:36:39 +03:00
res();
}, 250);
});
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-09-09 20:36:39 +03:00
{
action: "decryptWallet",
payload: {
password: authenticatePassword,
wallet: rawWallet,
},
},
(response) => {
if (response && !response?.error) {
setAuthenticatePassword("");
setExtstate("authenticated");
setWalletToBeDecryptedError("");
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage({ action: "userInfo" }, (response) => {
2024-09-09 20:36:39 +03:00
setIsLoading(false);
if (response && !response.error) {
setUserInfo(response);
}
});
getBalanceFunc();
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-09-09 20:36:39 +03:00
{ action: "getWalletInfo" },
(response) => {
if (response && response?.walletInfo) {
setRawWallet(response?.walletInfo);
}
}
);
} else if (response?.error) {
setIsLoading(false);
setWalletToBeDecryptedError(response.error);
}
2024-07-17 20:53:38 -04:00
}
2024-09-09 20:36:39 +03:00
);
} catch (error) {
setWalletToBeDecryptedError("Unable to authenticate. Wrong password");
}
};
// const handleBeforeUnload = (e)=> {
// const shouldClose = confirm('Are you sure you want to close this window? You may have unsaved changes.');
// if (!shouldClose) {
// // Prevent the window from closing
// e.preventDefault();
// e.returnValue = ''; // Required for Chrome
// } else {
// // Allow the window to close
// // No need to call preventDefault here; returnValue must be left empty
// }
// }
// useEffect(()=> {
// window.addEventListener('beforeunload', handleBeforeUnload);
// return ()=> {
// window.removeEventListener('beforeunload', handleBeforeUnload);
// }
// }, [])
useEffect(() => {
2024-09-22 15:16:36 +03:00
if (!isMainWindow || isMobile) return;
2024-09-09 20:36:39 +03:00
const handleBeforeUnload = (e) => {
e.preventDefault();
e.returnValue = ""; // This is required for Chrome to display the confirmation dialog.
2024-10-15 17:48:03 +03:00
return "";
2024-09-09 20:36:39 +03:00
};
// Add the event listener when the component mounts
window.addEventListener("beforeunload", handleBeforeUnload);
// Clean up the event listener when the component unmounts
return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, []);
useEffect(() => {
if (!isMainWindow) return;
// Handler for when the window gains focus
const handleFocus = () => {
setIsFocused(true);
2024-10-15 17:48:03 +03:00
if (isMobile) {
chrome?.runtime?.sendMessage({
action: "clearAllNotifications",
payload: {},
});
}
2024-10-15 17:48:03 +03:00
2024-09-09 20:36:39 +03:00
};
// Handler for when the window loses focus
const handleBlur = () => {
setIsFocused(false);
};
// Attach the event listeners
window.addEventListener("focus", handleFocus);
window.addEventListener("blur", handleBlur);
// Optionally, listen for visibility changes
const handleVisibilityChange = () => {
if (document.visibilityState === "visible") {
setIsFocused(true);
2024-10-15 17:48:03 +03:00
if (isMobile) {
chrome?.runtime?.sendMessage({
action: "clearAllNotifications",
payload: {},
});
}
2024-09-09 20:36:39 +03:00
} else {
setIsFocused(false);
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
// Cleanup the event listeners on component unmount
return () => {
window.removeEventListener("focus", handleFocus);
window.removeEventListener("blur", handleBlur);
document.removeEventListener("visibilitychange", handleVisibilityChange);
};
}, []);
const openPaymentInternal = (e) => {
const directAddress = e.detail?.address;
2024-10-15 17:48:03 +03:00
const name = e.detail?.name;
setIsOpenSendQort(true);
setPaymentTo(name || directAddress);
};
useEffect(() => {
subscribeToEvent("openPaymentInternal", openPaymentInternal);
return () => {
unsubscribeFromEvent("openPaymentInternal", openPaymentInternal);
};
}, []);
2024-09-09 20:36:39 +03:00
const registerName = async () => {
try {
if (!userInfo?.address) throw new Error("Your address was not found");
const fee = await getFee("REGISTER_NAME");
await show({
message: "Would you like to register this name?",
publishFee: fee.fee + " QORT",
});
setIsLoadingRegisterName(true);
new Promise((res, rej) => {
2024-09-12 05:01:36 +03:00
chrome?.runtime?.sendMessage(
2024-09-09 20:36:39 +03:00
{
action: "registerName",
payload: {
name: registerNameValue,
},
},
(response) => {
if (!response?.error) {
res(response);
setIsLoadingRegisterName(false);
setInfoSnack({
type: "success",
message:
"Successfully registered. It may take a couple of minutes for the changes to propagate",
});
setOpenRegisterName(false);
setRegisterNameValue("");
setOpenSnack(true);
setTxList((prev) => [
{
...response,
type: "register-name",
label: `Registered name: awaiting confirmation. This may take a couple minutes.`,
labelDone: `Registered name: success!`,
done: false,
},
...prev.filter((item) => !item.done),
]);
return;
2024-07-18 12:26:13 -04:00
}
2024-09-09 20:36:39 +03:00
setInfoSnack({
type: "error",
message: response?.error,
});
setOpenSnack(true);
rej(response.error);
}
);
2024-07-09 00:44:02 +03:00
});
} catch (error) {
2024-09-09 20:36:39 +03:00
if (error?.message) {
setInfoSnack({
type: "error",
message: error?.message,
});
}
} finally {
setIsLoadingRegisterName(false);
2024-07-17 20:53:38 -04:00
}
2024-09-09 20:36:39 +03:00
};
2024-07-09 00:44:02 +03:00
2024-10-15 17:48:03 +03:00
const renderProfile = () => {
2024-09-12 05:01:36 +03:00
return (
2024-10-15 17:48:03 +03:00
<AuthenticatedContainer
sx={{
width: isMobile ? "100vw" : "350px",
display: "flex",
backgroundColor: "var(--bg-2)",
}}
>
{isMobile && (
<Box
sx={{
padding: "10px",
display: "flex",
justifyContent: "flex-end",
}}
>
<CloseIcon
onClick={() => {
setIsOpenDrawerProfile(false);
}}
2024-09-12 05:01:36 +03:00
sx={{
2024-10-15 17:48:03 +03:00
cursor: "pointer",
color: "white",
2024-09-12 05:01:36 +03:00
}}
2024-10-15 17:48:03 +03:00
/>
</Box>
)}
<AuthenticatedContainerInnerLeft
sx={{
overflowY: isMobile && "auto",
}}
>
<Spacer height="48px" />
{authenticatedMode === "ltc" ? (
<>
<img src={ltcLogo} />
<Spacer height="32px" />
<CopyToClipboard text={rawWallet?.ltcAddress}>
<AddressBox>
{rawWallet?.ltcAddress?.slice(0, 6)}...
{rawWallet?.ltcAddress?.slice(-4)} <img src={Copy} />
</AddressBox>
</CopyToClipboard>
<Spacer height="10px" />
{ltcBalanceLoading && (
<CircularProgress color="success" size={16} />
)}
{!isNaN(+ltcBalance) && !ltcBalanceLoading && (
<Box
sx={{
gap: "10px",
display: "flex",
alignItems: "center",
}}
>
<TextP
sx={{
textAlign: "center",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
}}
>
{ltcBalance} LTC
</TextP>
<RefreshIcon
onClick={getLtcBalanceFunc}
sx={{
fontSize: "16px",
color: "white",
cursor: "pointer",
}}
/>
</Box>
)}
<AddressQRCode targetAddress={rawWallet?.ltcAddress} />
</>
) : (
<>
<MainAvatar myName={userInfo?.name} />
<Spacer height="32px" />
2024-09-12 05:01:36 +03:00
<TextP
sx={{
textAlign: "center",
lineHeight: "24px",
fontSize: "20px",
}}
>
2024-10-15 17:48:03 +03:00
{userInfo?.name}
2024-09-12 05:01:36 +03:00
</TextP>
2024-10-15 17:48:03 +03:00
<Spacer height="10px" />
<CopyToClipboard text={rawWallet?.address0}>
<AddressBox>
{rawWallet?.address0?.slice(0, 6)}...
{rawWallet?.address0?.slice(-4)} <img src={Copy} />
</AddressBox>
</CopyToClipboard>
<Spacer height="10px" />
{qortBalanceLoading && (
<CircularProgress color="success" size={16} />
)}
{!qortBalanceLoading && balance >= 0 && (
<Box
sx={{
gap: "10px",
display: "flex",
alignItems: "center",
}}
>
<TextP
sx={{
textAlign: "center",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
}}
>
{balance?.toFixed(2)} QORT
</TextP>
<RefreshIcon
onClick={getBalanceFunc}
sx={{
fontSize: "16px",
color: "white",
cursor: "pointer",
}}
/>
</Box>
)}
<Spacer height="35px" />
{userInfo && !userInfo?.name && (
<TextP
ref={registerNamePopoverRef}
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: 500,
cursor: "pointer",
marginTop: "10px",
color: "red",
textDecoration: "underline",
}}
onClick={() => {
setOpenRegisterName(true);
}}
>
REGISTER NAME
</TextP>
)}
<Spacer height="20px" />
<CustomButton
onClick={() => {
setIsOpenSendQort(true);
// setExtstate("send-qort");
setIsOpenDrawerProfile(false);
2024-09-12 05:01:36 +03:00
}}
2024-10-15 17:48:03 +03:00
>
Transfer QORT
</CustomButton>
<AddressQRCode targetAddress={rawWallet?.address0} />
</>
2024-09-12 05:01:36 +03:00
)}
<TextP
sx={{
textAlign: "center",
lineHeight: "24px",
2024-10-15 17:48:03 +03:00
fontSize: "12px",
fontWeight: 500,
cursor: "pointer",
marginTop: "10px",
textDecoration: "underline",
}}
onClick={() => {
2024-11-12 21:06:16 +02:00
executeEvent("addTab", { data: { service: 'APP', name: 'q-trade' } });
executeEvent("open-apps-mode", { });
2024-09-12 05:01:36 +03:00
}}
>
2024-11-12 21:06:16 +02:00
Get QORT at Q-Trade
2024-09-12 05:01:36 +03:00
</TextP>
2024-10-15 17:48:03 +03:00
</AuthenticatedContainerInnerLeft>
<AuthenticatedContainerInnerRight>
<Spacer height="20px" />
<img
onClick={() => {
setExtstate("download-wallet");
setIsOpenDrawerProfile(false);
}}
src={Download}
style={{
cursor: "pointer",
}}
/>
{!isMobile && (
<>
<Spacer height="20px" />
<img
src={Logout}
onClick={() => {
logoutFunc();
setIsOpenDrawerProfile(false);
2024-09-12 05:01:36 +03:00
}}
2024-10-15 17:48:03 +03:00
style={{
2024-09-12 05:01:36 +03:00
cursor: "pointer",
}}
/>
2024-10-15 17:48:03 +03:00
</>
2024-09-12 05:01:36 +03:00
)}
2024-10-15 17:48:03 +03:00
<Spacer height="20px" />
2024-09-12 05:01:36 +03:00
2024-10-15 17:48:03 +03:00
<ButtonBase
onClick={() => {
setIsSettingsOpen(true);
}}
>
<SettingsIcon
2024-09-12 05:01:36 +03:00
sx={{
2024-10-15 17:48:03 +03:00
color: "rgba(255, 255, 255, 0.5)",
}}
/>
</ButtonBase>
<Spacer height="20px" />
{authenticatedMode === "qort" && (
<img
onClick={() => {
setAuthenticatedMode("ltc");
}}
src={ltcLogo}
style={{
2024-09-12 05:01:36 +03:00
cursor: "pointer",
2024-10-15 17:48:03 +03:00
width: "20px",
height: "auto",
2024-09-12 05:01:36 +03:00
}}
2024-10-15 17:48:03 +03:00
/>
)}
{authenticatedMode === "ltc" && (
<img
2024-09-12 05:01:36 +03:00
onClick={() => {
2024-10-15 17:48:03 +03:00
setAuthenticatedMode("qort");
2024-09-12 05:01:36 +03:00
}}
2024-10-15 17:48:03 +03:00
src={qortLogo}
style={{
cursor: "pointer",
width: "20px",
height: "auto",
}}
/>
2024-09-12 05:01:36 +03:00
)}
2024-10-15 17:48:03 +03:00
</AuthenticatedContainerInnerRight>
</AuthenticatedContainer>
);
};
2024-09-12 05:01:36 +03:00
2024-04-14 14:57:30 +03:00
return (
2024-10-15 17:48:03 +03:00
<AppContainer
sx={{
height: isMobile ? "100%" : "100vh",
2024-10-22 20:12:54 +03:00
backgroundImage: desktopViewMode === 'apps' && 'url("appsBg.svg")',
backgroundSize: desktopViewMode === 'apps' && 'cover',
backgroundPosition: desktopViewMode === 'apps' && 'center',
backgroundRepeat: desktopViewMode === 'apps' && 'no-repeat',
2024-10-15 17:48:03 +03:00
}}
>
2024-10-22 20:12:54 +03:00
2024-04-14 14:57:30 +03:00
{extState === "not-authenticated" && (
2024-10-24 03:55:10 +03:00
<NotAuthenticated getRootProps={getRootProps} getInputProps={getInputProps} setExtstate={setExtstate} apiKey={apiKey} globalApiKey={globalApiKey} setApiKey={setApiKey} handleSetGlobalApikey={handleSetGlobalApikey}/>
2024-04-14 14:57:30 +03:00
)}
2024-04-14 21:14:13 +03:00
{/* {extState !== "not-authenticated" && (
2024-04-14 14:57:30 +03:00
<button onClick={logoutFunc}>logout</button>
2024-04-14 21:14:13 +03:00
)} */}
2024-10-15 17:48:03 +03:00
{extState === "authenticated" && isMainWindow && (
2024-09-09 20:36:39 +03:00
<MyContext.Provider
value={{
txList,
setTxList,
memberGroups,
setMemberGroups,
isShow,
onCancel,
onOk,
show,
message,
2024-10-15 17:48:03 +03:00
rootHeight,
2024-09-09 20:36:39 +03:00
}}
>
<Box
sx={{
width: "100vw",
2024-10-15 17:48:03 +03:00
height: isMobile ? "100%" : "100vh",
2024-09-09 20:36:39 +03:00
display: "flex",
2024-10-15 17:48:03 +03:00
flexDirection: isMobile ? "column" : "row",
overflow: isMobile && "hidden",
2024-09-09 20:36:39 +03:00
}}
>
<Group
2024-10-15 17:48:03 +03:00
logoutFunc={logoutFunc}
2024-09-09 20:36:39 +03:00
balance={balance}
userInfo={userInfo}
myAddress={address}
2024-09-09 20:36:39 +03:00
isFocused={isFocused}
isMain={isMain}
2024-09-12 05:01:36 +03:00
isOpenDrawerProfile={isOpenDrawerProfile}
2024-10-15 17:48:03 +03:00
setIsOpenDrawerProfile={setIsOpenDrawerProfile}
2024-10-22 20:12:54 +03:00
desktopViewMode={desktopViewMode}
setDesktopViewMode={setDesktopViewMode}
2024-09-09 20:36:39 +03:00
/>
2024-10-22 20:12:54 +03:00
{(!isMobile && desktopViewMode !== 'apps') && renderProfile()}
2024-09-09 20:36:39 +03:00
</Box>
2024-10-15 17:48:03 +03:00
<Box
sx={{
position: "fixed",
right: "25px",
bottom: "25px",
width: "350px",
zIndex: 100000,
}}
>
<TaskManger getUserInfo={getUserInfo} />
</Box>
2024-09-09 20:36:39 +03:00
</MyContext.Provider>
2024-04-14 14:57:30 +03:00
)}
{isOpenSendQort && isMainWindow && (
2024-10-15 17:48:03 +03:00
<Box
sx={{
width: "100%",
height: "100%",
position: "fixed",
background: "#27282c",
display: "flex",
flexDirection: "column",
alignItems: "center",
zIndex: 6,
}}
>
2024-04-14 21:14:13 +03:00
<Spacer height="22px" />
<Box
sx={{
display: "flex",
width: "100%",
justifyContent: "flex-start",
2024-04-14 23:01:28 +03:00
paddingLeft: "22px",
boxSizing: "border-box",
2024-04-14 21:14:13 +03:00
}}
>
<img
style={{
cursor: "pointer",
}}
onClick={returnToMain}
src={Return}
/>
</Box>
<Spacer height="35px" />
2024-04-14 23:01:28 +03:00
<Box
2024-04-14 21:14:13 +03:00
sx={{
2024-04-14 23:01:28 +03:00
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
2024-04-14 21:14:13 +03:00
}}
>
2024-04-14 23:01:28 +03:00
<TextP
sx={{
textAlign: "start",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 600,
}}
>
Transfer QORT
</TextP>
<Spacer height="35px" />
<TextP
sx={{
textAlign: "start",
lineHeight: "16px",
fontSize: "20px",
fontWeight: 600,
color: "rgba(255, 255, 255, 0.5)",
}}
>
Balance:
</TextP>
<TextP
sx={{
textAlign: "start",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
}}
>
2024-07-18 12:26:13 -04:00
{balance?.toFixed(2)} QORT
2024-04-14 23:01:28 +03:00
</TextP>
2024-04-14 21:14:13 +03:00
</Box>
<Spacer height="35px" />
2024-04-14 14:57:30 +03:00
<Box>
2024-04-14 21:14:13 +03:00
<CustomLabel htmlFor="standard-adornment-name">To</CustomLabel>
<Spacer height="5px" />
<CustomInput
2024-04-14 14:57:30 +03:00
id="standard-adornment-name"
value={paymentTo}
onChange={(e) => setPaymentTo(e.target.value)}
2024-04-14 21:14:13 +03:00
autoComplete="off"
2024-04-14 14:57:30 +03:00
/>
2024-04-14 21:14:13 +03:00
<Spacer height="6px" />
2024-04-14 23:01:28 +03:00
<CustomLabel htmlFor="standard-adornment-amount">
Amount
</CustomLabel>
2024-04-14 21:14:13 +03:00
<Spacer height="5px" />
<CustomInput
2024-04-14 14:57:30 +03:00
id="standard-adornment-amount"
type="number"
value={paymentAmount}
onChange={(e) => setPaymentAmount(+e.target.value)}
2024-04-14 21:14:13 +03:00
autoComplete="off"
2024-04-14 14:57:30 +03:00
/>
2024-04-14 21:14:13 +03:00
<Spacer height="6px" />
<CustomLabel htmlFor="standard-adornment-password">
2024-04-15 22:30:49 +03:00
Confirm Wallet Password
2024-04-14 21:14:13 +03:00
</CustomLabel>
<Spacer height="5px" />
2024-07-02 19:02:02 -04:00
<PasswordField
2024-04-14 14:57:30 +03:00
id="standard-adornment-password"
value={paymentPassword}
onChange={(e) => setPaymentPassword(e.target.value)}
2024-04-14 21:14:13 +03:00
autoComplete="off"
2024-04-14 14:57:30 +03:00
/>
</Box>
2024-04-16 13:25:36 +03:00
<Spacer height="10px" />
<ErrorText>{sendPaymentError}</ErrorText>
2024-04-16 13:25:36 +03:00
{/* <Typography>{sendPaymentSuccess}</Typography> */}
2024-04-14 21:14:13 +03:00
<Spacer height="25px" />
<CustomButton
2024-04-14 14:57:30 +03:00
onClick={() => {
sendCoinFunc();
}}
>
2024-04-14 21:14:13 +03:00
Send
</CustomButton>
</Box>
2024-07-12 23:44:21 -04:00
)}
2024-10-14 18:59:42 +03:00
2024-10-15 17:48:03 +03:00
{isShowQortalRequest && !isMainWindow && (
2024-10-14 18:59:42 +03:00
<>
2024-10-15 17:48:03 +03:00
<Spacer height="120px" />
<Box
sx={{
display: "flex",
justifyContent: "center",
width: "100%",
}}
>
2024-10-15 02:18:59 +03:00
<TextP
2024-10-15 17:48:03 +03:00
sx={{
lineHeight: 1.2,
maxWidth: "90%",
textAlign: "center",
}}
>
{messageQortalRequest?.text1}
</TextP>
2024-10-15 02:18:59 +03:00
</Box>
2024-10-15 17:48:03 +03:00
{messageQortalRequest?.text2 && (
<>
<Spacer height="10px" />
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequest?.text2}
</TextP>
</Box>
2024-10-15 23:51:14 +03:00
<Spacer height="15px" />
2024-10-15 17:48:03 +03:00
</>
)}
{messageQortalRequest?.text3 && (
<>
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequest?.text3}
</TextP>
<Spacer height="15px" />
</Box>
</>
)}
{messageQortalRequest?.text4 && (
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequest?.text4}
</TextP>
</Box>
)}
{messageQortalRequest?.html && (
<div
dangerouslySetInnerHTML={{ __html: messageQortalRequest?.html }}
/>
)}
<Spacer height="15px" />
2024-10-15 23:51:14 +03:00
<TextP
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: 700,
maxWidth: "90%",
}}
>
{messageQortalRequest?.highlightedText}
</TextP>
2024-10-15 17:48:03 +03:00
{messageQortalRequest?.fee && (
<>
2024-10-15 23:51:14 +03:00
<Spacer height="15px" />
2024-10-15 02:18:59 +03:00
<TextP
2024-10-15 17:48:03 +03:00
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
maxWidth: "90%",
}}
>
{'Fee: '}{messageQortalRequest?.fee}{' QORT'}
</TextP>
<Spacer height="15px" />
</>
)}
{messageQortalRequest?.checkbox1 && (
<Box
sx={{
display: "flex",
gap: "10px",
alignItems: "center",
justifyContent: "center",
width: "90%",
marginTop: "20px",
}}
>
2024-10-14 23:27:11 +03:00
<Checkbox
2024-10-15 17:48:03 +03:00
onChange={(e) => {
qortalRequestCheckbox1Ref.current = e.target.checked;
2024-10-14 23:27:11 +03:00
}}
edge="start"
tabIndex={-1}
disableRipple
defaultChecked={messageQortalRequest?.checkbox1?.value}
sx={{
"&.Mui-checked": {
color: "white", // Customize the color when checked
},
"& .MuiSvgIcon-root": {
color: "white",
},
}}
/>
2024-10-15 17:48:03 +03:00
<Typography
sx={{
fontSize: "14px",
}}
>
{messageQortalRequest?.checkbox1?.label}
</Typography>
</Box>
)}
<Spacer height="29px" />
<Box
2024-10-14 18:59:42 +03:00
sx={{
2024-10-15 17:48:03 +03:00
display: "flex",
alignItems: "center",
gap: "14px",
2024-10-14 18:59:42 +03:00
}}
>
2024-10-15 17:48:03 +03:00
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => onOkQortalRequest("accepted")}
>
accept
</CustomButton>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => onCancelQortalRequest()}
>
decline
</CustomButton>
</Box>
<ErrorText>{sendPaymentError}</ErrorText>
</>
2024-10-14 18:59:42 +03:00
)}
2024-09-09 20:36:39 +03:00
{extState === "web-app-request-buy-order" && !isMainWindow && (
2024-07-12 23:44:21 -04:00
<>
<Spacer height="100px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
The Application <br></br>{" "}
<TextItalic>{requestBuyOrder?.hostname}</TextItalic> <br></br>
2024-10-15 17:48:03 +03:00
<TextSpan>
is requesting {requestBuyOrder?.crosschainAtInfo?.length}{" "}
{`buy order${
requestBuyOrder?.crosschainAtInfo.length === 1 ? "" : "s"
}`}
</TextSpan>
2024-07-12 23:44:21 -04:00
</TextP>
<Spacer height="10px" />
<TextP
sx={{
textAlign: "center",
2024-07-18 00:05:45 -04:00
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
2024-07-12 23:44:21 -04:00
}}
>
2024-10-15 17:48:03 +03:00
{requestBuyOrder?.crosschainAtInfo?.reduce((latest, cur) => {
return latest + +cur?.qortAmount;
}, 0)}{" "}
QORT
2024-07-12 23:44:21 -04:00
</TextP>
<Spacer height="15px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
2024-07-18 00:05:45 -04:00
fontSize: "14px",
2024-07-12 23:44:21 -04:00
}}
>
FOR
</TextP>
<Spacer height="15px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
}}
>
2024-10-15 17:48:03 +03:00
{roundUpToDecimals(
requestBuyOrder?.crosschainAtInfo?.reduce((latest, cur) => {
return latest + +cur?.expectedForeignAmount;
}, 0)
)}
2024-09-18 00:08:19 +03:00
{` ${requestBuyOrder?.crosschainAtInfo?.[0]?.foreignBlockchain}`}
2024-07-12 23:44:21 -04:00
</TextP>
{/* <Spacer height="29px" />
<CustomLabel htmlFor="standard-adornment-password">
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
<PasswordField
id="standard-adornment-password"
value={paymentPassword}
onChange={(e) => setPaymentPassword(e.target.value)}
/> */}
<Spacer height="29px" />
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "14px",
}}
>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => confirmBuyOrder(false)}
>
accept
</CustomButton>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => confirmBuyOrder(true)}
>
decline
</CustomButton>
</Box>
<ErrorText>{sendPaymentError}</ErrorText>
</>
2024-04-14 14:57:30 +03:00
)}
2024-10-15 17:48:03 +03:00
2024-09-09 20:36:39 +03:00
{extState === "web-app-request-payment" && !isMainWindow && (
2024-04-14 14:57:30 +03:00
<>
2024-04-15 22:30:49 +03:00
<Spacer height="100px" />
2024-04-14 23:19:55 +03:00
2024-04-15 22:30:49 +03:00
<TextP
2024-04-14 23:19:55 +03:00
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
The Application <br></br>{" "}
<TextItalic>{sendqortState?.hostname}</TextItalic> <br></br>
<TextSpan>is requesting a payment</TextSpan>
</TextP>
<Spacer height="10px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
2024-04-15 22:30:49 +03:00
fontSize: "10px",
2024-04-14 23:19:55 +03:00
}}
2024-04-15 22:30:49 +03:00
>
{sendqortState?.description}
</TextP>
2024-04-14 23:19:55 +03:00
<Spacer height="15px" />
<TextP
2024-04-15 22:30:49 +03:00
sx={{
textAlign: "center",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 700,
}}
>
{sendqortState?.amount} QORT
</TextP>
2024-07-09 00:44:02 +03:00
{/* <Spacer height="29px" />
2024-04-14 23:19:55 +03:00
<CustomLabel htmlFor="standard-adornment-password">
2024-04-15 22:30:49 +03:00
Confirm Wallet Password
2024-04-14 23:19:55 +03:00
</CustomLabel>
<Spacer height="5px" />
2024-07-02 19:02:02 -04:00
<PasswordField
2024-04-14 14:57:30 +03:00
id="standard-adornment-password"
value={paymentPassword}
onChange={(e) => setPaymentPassword(e.target.value)}
2024-07-09 00:44:02 +03:00
/> */}
2024-04-15 22:30:49 +03:00
<Spacer height="29px" />
<Box
2024-04-14 23:19:55 +03:00
sx={{
display: "flex",
alignItems: "center",
gap: "14px",
}}
>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => confirmPayment(false)}
>
accept
</CustomButton>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => confirmPayment(true)}
>
decline
</CustomButton>
</Box>
<ErrorText>{sendPaymentError}</ErrorText>
2024-04-14 14:57:30 +03:00
</>
)}
2024-09-09 20:36:39 +03:00
{extState === "web-app-request-connection" && !isMainWindow && (
2024-04-14 14:57:30 +03:00
<>
2024-04-14 23:01:28 +03:00
<Spacer height="48px" />
2024-09-09 20:36:39 +03:00
<div
className="image-container"
style={{
width: "136px",
height: "154px",
}}
>
2024-04-15 22:30:49 +03:00
<img src={Logo1} className="base-image" />
<img src={Logo1Dark} className="hover-image" />
</div>
2024-04-14 23:01:28 +03:00
<Spacer height="38px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
2024-04-14 14:57:30 +03:00
>
2024-04-14 23:01:28 +03:00
The Application <br></br>{" "}
<TextItalic>{requestConnection?.hostname}</TextItalic> <br></br>
<TextSpan>is requestion a connection</TextSpan>
</TextP>
<Spacer height="38px" />
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "14px",
}}
2024-04-14 14:57:30 +03:00
>
2024-04-14 23:01:28 +03:00
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() =>
responseToConnectionRequest(
true,
requestConnection?.hostname,
requestConnection.interactionId
)
}
>
accept
</CustomButton>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() =>
responseToConnectionRequest(
false,
requestConnection?.hostname,
requestConnection.interactionId
)
}
>
decline
</CustomButton>
</Box>
2024-04-14 14:57:30 +03:00
</>
)}
2024-09-09 20:36:39 +03:00
{extState === "web-app-request-authentication" && !isMainWindow && (
2024-04-14 14:57:30 +03:00
<>
2024-04-14 23:01:28 +03:00
<Spacer height="48px" />
2024-09-09 20:36:39 +03:00
<div
className="image-container"
style={{
width: "136px",
height: "154px",
}}
>
2024-04-15 22:30:49 +03:00
<img src={Logo1} className="base-image" />
<img src={Logo1Dark} className="hover-image" />
</div>
2024-04-14 23:01:28 +03:00
<Spacer height="38px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
The Application <br></br>{" "}
<TextItalic>{requestConnection?.hostname}</TextItalic> <br></br>
<TextSpan>requests authentication</TextSpan>
</TextP>
<Spacer height="38px" />
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "14px",
}}
></Box>
<Spacer height="38px" />
<CustomButton {...getRootProps()}>
<input {...getInputProps()} />
Authenticate
</CustomButton>
<Spacer height="6px" />
<CustomButton
2024-04-14 21:14:13 +03:00
onClick={() => {
setExtstate("create-wallet");
}}
>
Create account
2024-04-14 23:01:28 +03:00
</CustomButton>
2024-04-14 14:57:30 +03:00
</>
)}
2024-09-09 20:36:39 +03:00
{rawWallet && extState === "wallet-dropped" && (
2024-07-09 00:44:02 +03:00
<>
<Spacer height="22px" />
<Box
sx={{
display: "flex",
width: "100%",
justifyContent: "flex-start",
paddingLeft: "22px",
boxSizing: "border-box",
}}
>
<img
style={{
cursor: "pointer",
}}
2024-07-17 20:53:38 -04:00
onClick={() => {
2024-07-09 00:44:02 +03:00
setRawWallet(null);
setExtstate("not-authenticated");
}}
src={Return}
/>
</Box>
<Spacer height="10px" />
2024-09-09 20:36:39 +03:00
<div
className="image-container"
style={{
width: "136px",
height: "154px",
}}
>
2024-07-09 00:44:02 +03:00
<img src={Logo1} className="base-image" />
<img src={Logo1Dark} className="hover-image" />
</div>
<Spacer height="35px" />
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
}}
>
<TextP
sx={{
textAlign: "start",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 600,
}}
>
Authenticate
</TextP>
</Box>
<Spacer height="35px" />
2024-07-17 20:53:38 -04:00
<>
<CustomLabel htmlFor="standard-adornment-password">
Wallet Password
</CustomLabel>
<Spacer height="5px" />
<PasswordField
id="standard-adornment-password"
value={authenticatePassword}
2024-09-09 20:36:39 +03:00
onChange={(e) => setAuthenticatePassword(e.target.value)}
2024-07-17 20:53:38 -04:00
onKeyDown={(e) => {
if (e.key === "Enter") {
authenticateWallet();
2024-07-09 00:44:02 +03:00
}
2024-07-17 20:53:38 -04:00
}}
/>
<Spacer height="20px" />
2024-09-09 20:36:39 +03:00
<CustomButton onClick={authenticateWallet}>
2024-07-17 20:53:38 -04:00
Authenticate
</CustomButton>
2024-09-09 20:36:39 +03:00
<ErrorText>{walletToBeDecryptedError}</ErrorText>
2024-07-17 20:53:38 -04:00
</>
2024-07-09 00:44:02 +03:00
</>
)}
2024-04-14 14:57:30 +03:00
{extState === "download-wallet" && (
<>
2024-04-15 22:30:49 +03:00
<Spacer height="22px" />
<Box
sx={{
display: "flex",
width: "100%",
justifyContent: "flex-start",
paddingLeft: "22px",
boxSizing: "border-box",
}}
>
<img
style={{
cursor: "pointer",
}}
onClick={returnToMain}
src={Return}
/>
</Box>
<Spacer height="10px" />
2024-09-09 20:36:39 +03:00
<div
className="image-container"
style={{
width: "136px",
height: "154px",
}}
>
2024-04-15 22:30:49 +03:00
<img src={Logo1} className="base-image" />
<img src={Logo1Dark} className="hover-image" />
2024-04-14 14:57:30 +03:00
</div>
2024-04-15 22:30:49 +03:00
<Spacer height="35px" />
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
}}
>
<TextP
sx={{
textAlign: "start",
lineHeight: "24px",
fontSize: "20px",
fontWeight: 600,
}}
>
Download Wallet
</TextP>
</Box>
<Spacer height="35px" />
2024-04-14 14:57:30 +03:00
{!walletToBeDownloaded && (
<>
2024-04-15 22:30:49 +03:00
<CustomLabel htmlFor="standard-adornment-password">
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
2024-07-02 19:02:02 -04:00
<PasswordField
2024-04-14 14:57:30 +03:00
id="standard-adornment-password"
value={walletToBeDownloadedPassword}
onChange={(e) =>
setWalletToBeDownloadedPassword(e.target.value)
}
/>
2024-04-15 22:30:49 +03:00
<Spacer height="20px" />
<CustomButton onClick={confirmPasswordToDownload}>
2024-04-14 14:57:30 +03:00
Confirm password
2024-04-15 22:30:49 +03:00
</CustomButton>
2024-09-09 20:36:39 +03:00
<ErrorText>{walletToBeDownloadedError}</ErrorText>
2024-04-14 14:57:30 +03:00
</>
)}
{walletToBeDownloaded && (
<>
2024-04-15 22:30:49 +03:00
<CustomButton onClick={saveFileToDiskFunc}>
Download wallet
</CustomButton>
2024-04-14 14:57:30 +03:00
</>
)}
</>
)}
{extState === "create-wallet" && (
<>
{!walletToBeDownloaded && (
<>
2024-07-17 20:53:38 -04:00
<Spacer height="22px" />
<Box
sx={{
display: "flex",
width: "100%",
justifyContent: "flex-start",
paddingLeft: "22px",
boxSizing: "border-box",
}}
>
<img
style={{
cursor: "pointer",
}}
onClick={() => {
2024-09-09 20:36:39 +03:00
setExtstate("not-authenticated");
2024-07-17 20:53:38 -04:00
}}
src={Return}
/>
</Box>
2024-04-15 22:30:49 +03:00
<Spacer height="15px" />
2024-09-09 20:36:39 +03:00
<div
className="image-container"
style={{
width: "136px",
height: "154px",
}}
>
2024-07-17 20:53:38 -04:00
<img src={Logo1} className="base-image" />
<img src={Logo1Dark} className="hover-image" />
</div>
2024-04-14 23:01:28 +03:00
<Spacer height="38px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
Set up your Qortal account
</TextP>
<Spacer height="14px" />
<CustomLabel htmlFor="standard-adornment-password">
2024-04-15 22:30:49 +03:00
Wallet Password
2024-04-14 23:01:28 +03:00
</CustomLabel>
<Spacer height="5px" />
2024-07-02 19:02:02 -04:00
<PasswordField
2024-04-14 14:57:30 +03:00
id="standard-adornment-password"
value={walletToBeDownloadedPassword}
onChange={(e) =>
setWalletToBeDownloadedPassword(e.target.value)
}
/>
2024-04-14 23:01:28 +03:00
<Spacer height="6px" />
<CustomLabel htmlFor="standard-adornment-password">
2024-04-15 22:30:49 +03:00
Confirm Wallet Password
2024-04-14 23:01:28 +03:00
</CustomLabel>
<Spacer height="5px" />
2024-07-02 19:02:02 -04:00
<PasswordField
2024-04-14 14:57:30 +03:00
id="standard-adornment-password"
value={walletToBeDownloadedPasswordConfirm}
onChange={(e) =>
setWalletToBeDownloadedPasswordConfirm(e.target.value)
}
/>
2024-04-14 23:01:28 +03:00
<Spacer height="17px" />
<CustomButton onClick={createAccountFunc}>
Create Account
</CustomButton>
2024-09-09 20:36:39 +03:00
<ErrorText>{walletToBeDownloadedError}</ErrorText>
2024-04-14 14:57:30 +03:00
</>
)}
{walletToBeDownloaded && (
<>
2024-04-14 23:01:28 +03:00
<Spacer height="48px" />
<img src={Success} />
<Spacer height="45px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
Congrats, youre all set up!
</TextP>
<Spacer height="100px" />
2024-04-15 22:30:49 +03:00
<CustomButton
onClick={() => {
saveFileToDiskFunc();
returnToMain();
}}
>
2024-04-14 23:01:28 +03:00
Backup Account
</CustomButton>
2024-04-14 14:57:30 +03:00
</>
)}
</>
)}
{isOpenSendQortSuccess && (
2024-10-15 17:48:03 +03:00
<Box
sx={{
width: "100%",
height: "100%",
position: "fixed",
background: "#27282c",
display: "flex",
flexDirection: "column",
alignItems: "center",
zIndex: 6,
}}
>
2024-04-15 22:30:49 +03:00
<Spacer height="48px" />
<img src={Success} />
<Spacer height="45px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
The transfer was succesful!
</TextP>
<Spacer height="100px" />
<CustomButton
onClick={() => {
returnToMain();
}}
>
Continue
</CustomButton>
</Box>
2024-04-15 22:30:49 +03:00
)}
{extState === "transfer-success-request" && (
<>
<Spacer height="48px" />
<img src={Success} />
<Spacer height="45px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
The transfer was succesful!
</TextP>
<Spacer height="100px" />
<CustomButton
onClick={() => {
window.close();
}}
>
Continue
</CustomButton>
</>
)}
2024-07-17 17:00:43 -04:00
{extState === "buy-order-submitted" && (
<>
<Spacer height="48px" />
<img src={Success} />
<Spacer height="45px" />
<TextP
sx={{
textAlign: "center",
lineHeight: "15px",
}}
>
Your buy order was submitted
</TextP>
<Spacer height="100px" />
<CustomButton
onClick={() => {
window.close();
}}
>
Close
</CustomButton>
</>
)}
2024-04-14 14:57:30 +03:00
{countdown && (
2024-04-14 23:01:28 +03:00
<Box
style={{
position: "absolute",
top: "20px",
left: "20px",
2024-04-14 14:57:30 +03:00
}}
>
2024-04-14 23:01:28 +03:00
{/* <Spacer height="25px"/> */}
<CountdownCircleTimer
isPlaying
duration={countdown}
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
colorsTime={[7, 5, 2, 0]}
onComplete={() => {
window.close();
}}
size={75}
strokeWidth={8}
>
{({ remainingTime }) => <TextP>{remainingTime}</TextP>}
</CountdownCircleTimer>
</Box>
2024-04-14 14:57:30 +03:00
)}
2024-04-15 22:30:49 +03:00
{isLoading && <Loader />}
2024-09-09 20:36:39 +03:00
{isShow && (
<Dialog
open={isShow}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Publish"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{message.message}
</DialogContentText>
<DialogContentText id="alert-dialog-description2">
publish fee: {message.publishFee}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCancel}>
Disagree
</Button>
<Button variant="contained" onClick={onOk} autoFocus>
Agree
</Button>
</DialogActions>
</Dialog>
2024-10-21 11:40:45 +03:00
)}
{isShowUnsavedChanges && (
<Dialog
open={isShowUnsavedChanges}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Warning"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{messageUnsavedChanges.message}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCancelUnsavedChanges}>
Cancel
</Button>
<Button variant="contained" onClick={onOkUnsavedChanges} autoFocus>
Continue to Logout
</Button>
</DialogActions>
</Dialog>
)}
{isShowQortalRequestExtension && isMainWindow && (
<Dialog
open={isShowQortalRequestExtension}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<CountdownCircleTimer
isPlaying
duration={30}
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
colorsTime={[7, 5, 2, 0]}
onComplete={() => {
onCancelQortalRequestExtension()
}}
size={50}
strokeWidth={5}
>
{({ remainingTime }) => <TextP>{remainingTime}</TextP>}
</CountdownCircleTimer>
<Box sx={{
display: 'flex',
padding: '20px',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'flex-start',
minHeight: '400px',
maxHeight: '90vh',
overflow: 'auto'
}}>
<Box
sx={{
display: "flex",
justifyContent: "center",
width: "100%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
maxWidth: "90%",
textAlign: "center",
}}
>
{messageQortalRequestExtension?.text1}
</TextP>
</Box>
{messageQortalRequestExtension?.text2 && (
<>
<Spacer height="10px" />
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequestExtension?.text2}
</TextP>
</Box>
<Spacer height="15px" />
</>
)}
{messageQortalRequestExtension?.text3 && (
<>
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequestExtension?.text3}
</TextP>
<Spacer height="15px" />
</Box>
</>
)}
{messageQortalRequestExtension?.text4 && (
<Box
sx={{
display: "flex",
justifyContent: "flex-start",
width: "90%",
}}
>
<TextP
sx={{
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
}}
>
{messageQortalRequestExtension?.text4}
</TextP>
</Box>
)}
{messageQortalRequestExtension?.html && (
<div
dangerouslySetInnerHTML={{ __html: messageQortalRequestExtension?.html }}
/>
)}
<Spacer height="15px" />
<TextP
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: 700,
maxWidth: "90%",
}}
>
{messageQortalRequestExtension?.highlightedText}
</TextP>
{messageQortalRequestExtension?.fee && (
<>
<Spacer height="15px" />
<TextP
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
maxWidth: "90%",
}}
>
{'Fee: '}{messageQortalRequestExtension?.fee}{' QORT'}
</TextP>
<Spacer height="15px" />
</>
)}
2024-11-12 21:06:16 +02:00
{messageQortalRequestExtension?.foreignFee && (
<>
<Spacer height="15px" />
<TextP
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
maxWidth: "90%",
}}
>
{"Foreign Fee: "}
{messageQortalRequestExtension?.foreignFee}
</TextP>
<Spacer height="15px" />
</>
)}
2024-10-21 11:40:45 +03:00
{messageQortalRequestExtension?.checkbox1 && (
<Box
sx={{
display: "flex",
gap: "10px",
alignItems: "center",
justifyContent: "center",
width: "90%",
marginTop: "20px",
}}
>
<Checkbox
onChange={(e) => {
qortalRequestCheckbox1Ref.current = e.target.checked;
}}
edge="start"
tabIndex={-1}
disableRipple
defaultChecked={messageQortalRequestExtension?.checkbox1?.value}
sx={{
"&.Mui-checked": {
color: "white", // Customize the color when checked
},
"& .MuiSvgIcon-root": {
color: "white",
},
}}
/>
<Typography
sx={{
fontSize: "14px",
}}
>
{messageQortalRequestExtension?.checkbox1?.label}
</Typography>
</Box>
)}
<Spacer height="29px" />
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "14px",
}}
>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => onOkQortalRequestExtension("accepted")}
>
accept
</CustomButton>
<CustomButton
sx={{
minWidth: "102px",
}}
onClick={() => onCancelQortalRequestExtension()}
>
decline
</CustomButton>
</Box>
<ErrorText>{sendPaymentError}</ErrorText>
</Box>
</Dialog>
2024-09-09 20:36:39 +03:00
)}
<Popover
open={openRegisterName}
anchorEl={registerNamePopoverRef.current}
onClose={() => {
setOpenRegisterName(false);
setRegisterNameValue("");
}}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
style={{ marginTop: "8px" }}
>
<Box
sx={{
width: "325px",
height: "250px",
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "10px",
padding: "10px",
}}
>
<Label>Choose a name</Label>
<Input
onChange={(e) => setRegisterNameValue(e.target.value)}
value={registerNameValue}
placeholder="Choose a name"
/>
<Spacer height="25px" />
<LoadingButton
loading={isLoadingRegisterName}
loadingPosition="start"
variant="contained"
disabled={!registerNameValue}
onClick={registerName}
>
Register Name
</LoadingButton>
</Box>
</Popover>
2024-09-24 17:09:13 +03:00
{isSettingsOpen && (
2024-10-15 17:48:03 +03:00
<Settings open={isSettingsOpen} setOpen={setIsSettingsOpen} />
2024-09-24 17:09:13 +03:00
)}
2024-09-09 20:36:39 +03:00
<CustomizedSnackbars
open={openSnack}
setOpen={setOpenSnack}
info={infoSnack}
setInfo={setInfoSnack}
/>
2024-10-15 17:48:03 +03:00
<DrawerComponent
open={isOpenDrawerProfile}
setOpen={setIsOpenDrawerProfile}
>
{renderProfile()}
</DrawerComponent>
2024-04-14 21:14:13 +03:00
</AppContainer>
2024-04-14 14:57:30 +03:00
);
}
export default App;