mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-02-11 17:55:49 +00:00
dynamic remote node feature
This commit is contained in:
parent
4f343178bc
commit
aeeac2fdaa
28
src/App.tsx
28
src/App.tsx
@ -78,7 +78,9 @@ import { Label } from "./components/Group/AddGroup";
|
||||
import { CustomizedSnackbars } from "./components/Snackbar/Snackbar";
|
||||
import SettingsIcon from "@mui/icons-material/Settings";
|
||||
import {
|
||||
cleanUrl,
|
||||
getFee,
|
||||
getProtocol,
|
||||
groupApi,
|
||||
groupApiLocal,
|
||||
groupApiSocket,
|
||||
@ -147,7 +149,7 @@ const defaultValues: MyContextInterface = {
|
||||
message: "",
|
||||
},
|
||||
};
|
||||
export let isMobile = false;
|
||||
export let isMobile = true;
|
||||
|
||||
const isMobileDevice = () => {
|
||||
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
||||
@ -226,7 +228,7 @@ export const getBaseApiReact = (customApi?: string) => {
|
||||
}
|
||||
|
||||
if (globalApiKey) {
|
||||
return groupApiLocal;
|
||||
return globalApiKey?.url;
|
||||
} else {
|
||||
return groupApi;
|
||||
}
|
||||
@ -252,7 +254,7 @@ export const getBaseApiReactSocket = (customApi?: string) => {
|
||||
}
|
||||
|
||||
if (globalApiKey) {
|
||||
return groupApiSocketLocal;
|
||||
return `${getProtocol(globalApiKey?.url) === 'http' ? 'ws://': 'wss://'}${cleanUrl(globalApiKey?.url)}`
|
||||
} else {
|
||||
return groupApiSocket;
|
||||
}
|
||||
@ -329,7 +331,6 @@ function App() {
|
||||
const [infoSnack, setInfoSnack] = useState(null);
|
||||
const [openSnack, setOpenSnack] = useState(false);
|
||||
const [hasLocalNode, setHasLocalNode] = useState(false);
|
||||
const [openAdvancedSettings, setOpenAdvancedSettings] = useState(false);
|
||||
const [isOpenDrawerProfile, setIsOpenDrawerProfile] = useState(false);
|
||||
const [apiKey, setApiKey] = useState("");
|
||||
const [isOpenSendQort, setIsOpenSendQort] = useState(false);
|
||||
@ -406,7 +407,7 @@ function App() {
|
||||
console.log('response', response)
|
||||
handleSetGlobalApikey(response)
|
||||
setApiKey(response);
|
||||
setOpenAdvancedSettings(true);
|
||||
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
@ -420,18 +421,7 @@ function App() {
|
||||
isFocusedRef.current = isFocused;
|
||||
}, [isFocused]);
|
||||
|
||||
// Handler for file selection
|
||||
const handleFileChangeApiKey = (event) => {
|
||||
const file = event.target.files[0]; // Get the selected file
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const text = e.target.result; // Get the file content
|
||||
setApiKey(text); // Store the file content in the state
|
||||
};
|
||||
reader.readAsText(file); // Read the file as text
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// const checkIfUserHasLocalNode = useCallback(async () => {
|
||||
// try {
|
||||
@ -1068,8 +1058,6 @@ function App() {
|
||||
setWalletToBeDownloadedError("");
|
||||
setSendqortState(null);
|
||||
setHasLocalNode(false);
|
||||
setOpenAdvancedSettings(false);
|
||||
setConfirmUseOfLocal(false);
|
||||
setTxList([]);
|
||||
setMemberGroups([]);
|
||||
resetAllRecoil()
|
||||
@ -1563,7 +1551,7 @@ function App() {
|
||||
>
|
||||
|
||||
{extState === "not-authenticated" && (
|
||||
<NotAuthenticated getRootProps={getRootProps} getInputProps={getInputProps} setExtstate={setExtstate} setOpenAdvancedSettings={setOpenAdvancedSettings} openAdvancedSettings={openAdvancedSettings} handleFileChangeApiKey={handleFileChangeApiKey} apiKey={apiKey} globalApiKey={globalApiKey} setApiKey={setApiKey} handleSetGlobalApikey={handleSetGlobalApikey}/>
|
||||
<NotAuthenticated getRootProps={getRootProps} getInputProps={getInputProps} setExtstate={setExtstate} apiKey={apiKey} globalApiKey={globalApiKey} setApiKey={setApiKey} handleSetGlobalApikey={handleSetGlobalApikey}/>
|
||||
)}
|
||||
{/* {extState !== "not-authenticated" && (
|
||||
<button onClick={logoutFunc}>logout</button>
|
||||
|
@ -1,11 +1,16 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Spacer } from "../common/Spacer";
|
||||
import { CustomButton, TextItalic, TextP, TextSpan } from "../App-styles";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
FormControlLabel,
|
||||
Input,
|
||||
Switch,
|
||||
Tooltip,
|
||||
Typography,
|
||||
@ -14,14 +19,15 @@ import Logo1 from "../assets/svgs/Logo1.svg";
|
||||
import Logo1Dark from "../assets/svgs/Logo1Dark.svg";
|
||||
import Info from "../assets/svgs/Info.svg";
|
||||
import { CustomizedSnackbars } from "../components/Snackbar/Snackbar";
|
||||
import { set } from "lodash";
|
||||
import { cleanUrl, isUsingLocal } from "../background";
|
||||
|
||||
export const NotAuthenticated = ({
|
||||
getRootProps,
|
||||
getInputProps,
|
||||
setExtstate,
|
||||
setOpenAdvancedSettings,
|
||||
openAdvancedSettings,
|
||||
handleFileChangeApiKey,
|
||||
|
||||
|
||||
apiKey,
|
||||
setApiKey,
|
||||
globalApiKey,
|
||||
@ -33,6 +39,36 @@ export const NotAuthenticated = ({
|
||||
const [useLocalNode, setUseLocalNode] = useState(false);
|
||||
const [openSnack, setOpenSnack] = React.useState(false);
|
||||
const [infoSnack, setInfoSnack] = React.useState(null);
|
||||
const [show, setShow] = React.useState(false);
|
||||
const [mode, setMode] = React.useState("list");
|
||||
const [customNodes, setCustomNodes] = React.useState(null);
|
||||
const [currentNode, setCurrentNode] = React.useState({
|
||||
url: "http://127.0.0.1:12391",
|
||||
});
|
||||
const [importedApiKey, setImportedApiKey] = React.useState(null);
|
||||
//add and edit states
|
||||
const [url, setUrl] = React.useState("http://");
|
||||
const [customApikey, setCustomApiKey] = React.useState("");
|
||||
const [customNodeToSaveIndex, setCustomNodeToSaveIndex] =
|
||||
React.useState(null);
|
||||
const importedApiKeyRef = useRef(null)
|
||||
const currentNodeRef = useRef(null)
|
||||
|
||||
const isLocal = cleanUrl(currentNode?.url) === "127.0.0.1:12391";
|
||||
const handleFileChangeApiKey = (event) => {
|
||||
const file = event.target.files[0]; // Get the selected file
|
||||
console.log('file', file)
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const text = e.target.result; // Get the file content
|
||||
console.log('text', text)
|
||||
|
||||
setImportedApiKey(text); // Store the file content in the state
|
||||
};
|
||||
reader.readAsText(file); // Read the file as text
|
||||
}
|
||||
};
|
||||
|
||||
const checkIfUserHasLocalNode = useCallback(async () => {
|
||||
try {
|
||||
@ -44,7 +80,7 @@ export const NotAuthenticated = ({
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data?.syncPercent) {
|
||||
if (data?.height) {
|
||||
setHasLocalNode(true);
|
||||
}
|
||||
} catch (error) {}
|
||||
@ -54,14 +90,55 @@ export const NotAuthenticated = ({
|
||||
checkIfUserHasLocalNode();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "getCustomNodesFromStorage" },
|
||||
(response) => {
|
||||
if (response) {
|
||||
console.log("response", response);
|
||||
setCustomNodes(response || []);
|
||||
}
|
||||
}
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(()=> {
|
||||
importedApiKeyRef.current = importedApiKey
|
||||
}, [importedApiKey])
|
||||
useEffect(()=> {
|
||||
currentNodeRef.current = currentNode
|
||||
}, [currentNode])
|
||||
|
||||
console.log('currentNode', currentNode)
|
||||
|
||||
const validateApiKey = useCallback(async (key) => {
|
||||
try {
|
||||
const url = `http://127.0.0.1:12391/admin/apikey/test`;
|
||||
console.log('currentNodeRef.current', currentNodeRef.current, key)
|
||||
if(!currentNodeRef.current) return
|
||||
const isLocalKey = cleanUrl(key?.url) === "127.0.0.1:12391";
|
||||
const isCurrentNodeLocal = cleanUrl(currentNodeRef.current?.url) === "127.0.0.1:12391";
|
||||
if(isLocalKey && !isCurrentNodeLocal) {
|
||||
setIsValidApiKey(false);
|
||||
setUseLocalNode(false);
|
||||
return
|
||||
}
|
||||
let payload = {};
|
||||
|
||||
if (currentNodeRef.current?.url === "http://127.0.0.1:12391") {
|
||||
payload = {
|
||||
apikey: importedApiKeyRef.current || key?.apikey,
|
||||
url: currentNode?.url,
|
||||
};
|
||||
} else if(currentNodeRef.current) {
|
||||
payload = currentNodeRef.current;
|
||||
}
|
||||
console.log('payload', payload)
|
||||
const url = `${payload?.url}/admin/apikey/test`;
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
accept: "text/plain",
|
||||
"X-API-KEY": key, // Include the API key here
|
||||
"X-API-KEY": payload?.apikey, // Include the API key here
|
||||
},
|
||||
});
|
||||
|
||||
@ -69,7 +146,6 @@ export const NotAuthenticated = ({
|
||||
const data = await response.text();
|
||||
console.log("data", data);
|
||||
if (data === "true") {
|
||||
const payload = key;
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "setApiKey", payload },
|
||||
(response) => {
|
||||
@ -107,6 +183,44 @@ export const NotAuthenticated = ({
|
||||
}
|
||||
}, [apiKey]);
|
||||
|
||||
const addCustomNode = () => {
|
||||
setMode("add-node");
|
||||
};
|
||||
|
||||
const saveCustomNodes = (myNodes) => {
|
||||
let nodes = [...(myNodes || [])];
|
||||
console.log("customNodeToSaveIndex", customNodeToSaveIndex);
|
||||
if (customNodeToSaveIndex !== null) {
|
||||
nodes.splice(customNodeToSaveIndex, 1, {
|
||||
url,
|
||||
apikey: customApikey,
|
||||
});
|
||||
} else if (url && customApikey) {
|
||||
nodes.push({
|
||||
url,
|
||||
apikey: customApikey,
|
||||
});
|
||||
}
|
||||
|
||||
setCustomNodes(nodes);
|
||||
setCustomNodeToSaveIndex(null);
|
||||
if (!nodes) return;
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "setCustomNodes", nodes },
|
||||
(response) => {
|
||||
console.log("setCustomNodes", response);
|
||||
if (response) {
|
||||
setMode("list");
|
||||
setUrl("http://");
|
||||
setCustomApiKey("");
|
||||
// add alert
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
console.log("render customNodes", customNodes, mode);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Spacer height="48px" />
|
||||
@ -172,7 +286,16 @@ export const NotAuthenticated = ({
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Spacer height="15px" />
|
||||
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "12px",
|
||||
visibility: !useLocalNode && 'hidden'
|
||||
}}
|
||||
>
|
||||
{"Using node: "} {apiKey?.url}
|
||||
</Typography>
|
||||
<>
|
||||
<Spacer height="15px" />
|
||||
<Box
|
||||
@ -196,97 +319,71 @@ export const NotAuthenticated = ({
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
sx={{
|
||||
'& .MuiSwitch-switchBase.Mui-checked': {
|
||||
color: '#5EB049',
|
||||
},
|
||||
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiSwitch-switchBase.Mui-checked": {
|
||||
color: "#5EB049",
|
||||
},
|
||||
"& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track":
|
||||
{
|
||||
backgroundColor: "white", // Change track color when checked
|
||||
},
|
||||
}}
|
||||
checked={useLocalNode}
|
||||
onChange={(event) => {
|
||||
if (event.target.checked) {
|
||||
validateApiKey(apiKey);
|
||||
validateApiKey(currentNode);
|
||||
} else {
|
||||
setUseLocalNode(false);
|
||||
const payload = null;
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "setApiKey", payload },
|
||||
(response) => {
|
||||
console.log("setApiKey", response);
|
||||
if (response) {
|
||||
globalApiKey = payload;
|
||||
setApiKey(payload);
|
||||
handleSetGlobalApikey(payload);
|
||||
if (!globalApiKey) {
|
||||
setUseLocalNode(false);
|
||||
setOpenAdvancedSettings(false);
|
||||
setApiKey("");
|
||||
setCurrentNode({
|
||||
url: "http://127.0.0.1:12391",
|
||||
})
|
||||
setUseLocalNode(false)
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "setApiKey", payload:null },
|
||||
(response) => {
|
||||
console.log("setApiKey", response);
|
||||
if (response) {
|
||||
setApiKey(payload);
|
||||
handleSetGlobalApikey(payload);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
}}
|
||||
disabled={false}
|
||||
defaultChecked
|
||||
/>
|
||||
}
|
||||
label="Use Local Node"
|
||||
label={`Use ${isLocal ? 'Local' : 'Custom'} Node`}
|
||||
/>
|
||||
</Box>
|
||||
{currentNode?.url === "http://127.0.0.1:12391" && (
|
||||
<>
|
||||
<Button variant="contained" component="label">
|
||||
{apiKey ? "Change " : "Import "} apiKey.txt
|
||||
<input
|
||||
type="file"
|
||||
accept=".txt"
|
||||
hidden
|
||||
onChange={handleFileChangeApiKey} // File input handler
|
||||
/>
|
||||
</Button>
|
||||
<Spacer height="5px" />
|
||||
|
||||
<>
|
||||
<Button variant="contained" component="label">
|
||||
{apiKey ? "Change " : "Import "} apiKey.txt
|
||||
<input
|
||||
type="file"
|
||||
accept=".txt"
|
||||
hidden
|
||||
onChange={handleFileChangeApiKey} // File input handler
|
||||
/>
|
||||
</Button>
|
||||
<Spacer height="5px" />
|
||||
|
||||
<Spacer height="5px" />
|
||||
{apiKey && (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const payload = null;
|
||||
chrome?.runtime?.sendMessage(
|
||||
{ action: "setApiKey", payload },
|
||||
(response) => {
|
||||
console.log("setApiKey", response);
|
||||
if (response) {
|
||||
globalApiKey = payload;
|
||||
setApiKey(payload);
|
||||
if (!globalApiKey) {
|
||||
setUseLocalNode(false);
|
||||
setOpenAdvancedSettings(false);
|
||||
setApiKey("");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}}
|
||||
variant="contained"
|
||||
sx={{
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Clear Apikey
|
||||
</Button>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "12px",
|
||||
}}
|
||||
>
|
||||
{"Apikey : "} {apiKey}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
setShow(true);
|
||||
}}
|
||||
variant="contained"
|
||||
component="label"
|
||||
>
|
||||
Choose custom node
|
||||
</Button>
|
||||
</>
|
||||
</Box>
|
||||
</>
|
||||
@ -296,6 +393,223 @@ export const NotAuthenticated = ({
|
||||
info={infoSnack}
|
||||
setInfo={setInfoSnack}
|
||||
/>
|
||||
{show && (
|
||||
<Dialog
|
||||
open={show}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
fullWidth
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">{"Custom nodes"}</DialogTitle>
|
||||
<DialogContent>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100% !important",
|
||||
overflow: "auto",
|
||||
height: "60vh",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{mode === "list" && (
|
||||
<Box
|
||||
sx={{
|
||||
gap: "20px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "white",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
http://127.0.0.1:12391
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
disabled={currentNode?.url === "http://127.0.0.1:12391"}
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setCurrentNode({
|
||||
url: "http://127.0.0.1:12391",
|
||||
});
|
||||
setMode("list");
|
||||
setShow(false);
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
Choose
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{customNodes?.map((node, index) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "white",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
{node?.url}
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
disabled={currentNode?.url === node?.url}
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setCurrentNode({
|
||||
url: node?.url,
|
||||
apikey: node?.apikey,
|
||||
});
|
||||
setMode("list");
|
||||
setShow(false);
|
||||
setIsValidApiKey(false);
|
||||
setUseLocalNode(false);
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
Choose
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setCustomApiKey(node?.apikey);
|
||||
setUrl(node?.url);
|
||||
setMode("add-node");
|
||||
setCustomNodeToSaveIndex(index);
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const nodesToSave = [
|
||||
...(customNodes || []),
|
||||
].filter((item) => item?.url !== node?.url);
|
||||
console.log(
|
||||
"nodesToSave",
|
||||
nodesToSave,
|
||||
customNodes,
|
||||
node
|
||||
);
|
||||
|
||||
saveCustomNodes(nodesToSave);
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
{mode === "add-node" && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
placeholder="Url"
|
||||
value={url}
|
||||
onChange={(e) => {
|
||||
setUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
placeholder="Api key"
|
||||
value={customApikey}
|
||||
onChange={(e) => {
|
||||
setCustomApiKey(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
{mode === "list" && (
|
||||
<>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
setShow(false);
|
||||
}}
|
||||
autoFocus
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{mode === "list" && (
|
||||
<Button variant="contained" onClick={addCustomNode}>
|
||||
Add
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{mode === "add-node" && (
|
||||
<>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
setMode("list");
|
||||
setCustomNodeToSaveIndex(null);
|
||||
}}
|
||||
>
|
||||
Return to list
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!customApikey || !url}
|
||||
onClick={() => saveCustomNodes(customNodes)}
|
||||
autoFocus
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -31,6 +31,19 @@ import { Sha256 } from "asmcrypto.js";
|
||||
import { TradeBotRespondMultipleRequest } from "./transactions/TradeBotRespondMultipleRequest";
|
||||
import { RESOURCE_TYPE_NUMBER_GROUP_CHAT_REACTIONS } from "./constants/resourceTypes";
|
||||
|
||||
export function cleanUrl(url) {
|
||||
return url?.replace(/^(https?:\/\/)?(www\.)?/, '');
|
||||
}
|
||||
export function getProtocol(url) {
|
||||
if (url?.startsWith('https://')) {
|
||||
return 'https';
|
||||
} else if (url?.startsWith('http://')) {
|
||||
return 'http';
|
||||
} else {
|
||||
return 'unknown'; // If neither protocol is present
|
||||
}
|
||||
}
|
||||
|
||||
let lastGroupNotification;
|
||||
export const groupApi = "https://ext-node.qortal.link";
|
||||
export const groupApiSocket = "wss://ext-node.qortal.link";
|
||||
@ -40,6 +53,7 @@ const timeDifferenceForNotificationChatsBackground = 600000;
|
||||
const requestQueueAnnouncements = new RequestQueueWithPromise(1);
|
||||
let isMobile = false;
|
||||
|
||||
|
||||
const isMobileDevice = () => {
|
||||
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
||||
|
||||
@ -106,6 +120,17 @@ const getApiKeyFromStorage = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const getCustomNodesFromStorage = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.get("customNodes", (result) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
return reject(chrome.runtime.lastError);
|
||||
}
|
||||
resolve(result.customNodes || null); // Return null if apiKey isn't found
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// const getArbitraryEndpoint = ()=> {
|
||||
// const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
||||
// if (apiKey) {
|
||||
@ -130,7 +155,7 @@ export const getBaseApi = async (customApi?: string) => {
|
||||
|
||||
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
||||
if (apiKey) {
|
||||
return groupApiLocal;
|
||||
return apiKey?.url;
|
||||
} else {
|
||||
return groupApi;
|
||||
}
|
||||
@ -145,15 +170,7 @@ export const isUsingLocal = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const createEndpointSocket = async (endpoint) => {
|
||||
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
||||
|
||||
if (apiKey) {
|
||||
return `${groupApiSocketLocal}${endpoint}`;
|
||||
} else {
|
||||
return `${groupApiSocket}${endpoint}`;
|
||||
}
|
||||
};
|
||||
|
||||
export const createEndpoint = async (endpoint, customApi?: string) => {
|
||||
if (customApi) {
|
||||
@ -165,7 +182,7 @@ export const createEndpoint = async (endpoint, customApi?: string) => {
|
||||
if (apiKey) {
|
||||
// Check if the endpoint already contains a query string
|
||||
const separator = endpoint.includes("?") ? "&" : "?";
|
||||
return `${groupApiLocal}${endpoint}${separator}apiKey=${apiKey}`;
|
||||
return `${apiKey?.url}${endpoint}${separator}apiKey=${apiKey?.apikey}`;
|
||||
} else {
|
||||
return `${groupApi}${endpoint}`;
|
||||
}
|
||||
@ -1816,7 +1833,7 @@ async function createBuyOrderTx({ crosschainAtInfo, useLocal }) {
|
||||
let responseVar
|
||||
const txn = new TradeBotRespondMultipleRequest().createTransaction(message)
|
||||
const apiKey = await getApiKeyFromStorage();
|
||||
const responseFetch = await fetch(`http://127.0.0.1:12391/crosschain/tradebot/respondmultiple?apiKey=${apiKey}`, {
|
||||
const responseFetch = await fetch(`${apiKey?.url}/crosschain/tradebot/respondmultiple?apiKey=${apiKey?.apikey}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@ -3291,6 +3308,16 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case "setCustomNodes": {
|
||||
const { nodes } = request;
|
||||
|
||||
// Save the customNodes in chrome.storage.local for persistence
|
||||
chrome.storage.local.set({ customNodes: nodes }, () => {
|
||||
sendResponse(true);
|
||||
});
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case "getApiKey": {
|
||||
getApiKeyFromStorage()
|
||||
.then((res) => {
|
||||
@ -3303,6 +3330,19 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case "getCustomNodesFromStorage": {
|
||||
getCustomNodesFromStorage()
|
||||
.then((res) => {
|
||||
sendResponse(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
sendResponse({ error: error.message });
|
||||
console.error(error.message);
|
||||
});
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
case "notifyAdminRegenerateSecretKey": {
|
||||
const { groupName, adminAddress } = request.payload;
|
||||
notifyAdminRegenerateSecretKey({ groupName, adminAddress })
|
||||
|
@ -28,7 +28,7 @@ export const useAppFullScreen = (setFullScreen) => {
|
||||
}, []);
|
||||
|
||||
const toggleFullScreen = useCallback(() => {
|
||||
if(!isMobile) return
|
||||
if(!isMobile || isMobile) return
|
||||
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
|
||||
exitFullScreen();
|
||||
setFullScreen(false)
|
||||
|
Loading…
x
Reference in New Issue
Block a user