added apps to dev mode

This commit is contained in:
2025-01-20 21:52:45 +02:00
parent d1f070555f
commit e8e8911972
4 changed files with 390 additions and 312 deletions

View File

@@ -332,7 +332,7 @@ export const AppsDevMode = ({ mode, setMode, show , myName, goToHome, setDesktop
isSelected={tab?.tabId === selectedTab?.tabId}
app={tab}
ref={iframeRefs.current[tab.tabId]}
isDevMode={true}
isDevMode={tab?.service ? false : true}
/>
);
})}

View File

@@ -7,7 +7,7 @@ import {
AppsContainer,
AppsParent,
} from "./Apps-styles";
import {Buffer} from 'buffer'
import { Buffer } from "buffer";
import {
Avatar,
@@ -29,249 +29,239 @@ import { Spacer } from "../../common/Spacer";
import { useModal } from "../../common/useModal";
import { createEndpoint, isUsingLocal } from "../../background";
import { Label } from "../Group/AddGroup";
import ShortUniqueId from "short-unique-id";
import swaggerSVG from '../../assets/svgs/swagger.svg'
const uid = new ShortUniqueId({ length: 8 });
export const AppsDevModeHome = ({
setMode,
myApp,
myWebsite,
availableQapps,
myName
myName,
}) => {
const [domain, setDomain] = useState("127.0.0.1");
const [port, setPort] = useState("");
const [selectedPreviewFile, setSelectedPreviewFile] = useState(null);
const [domain, setDomain] = useState("127.0.0.1");
const [port, setPort] = useState("");
const [selectedPreviewFile, setSelectedPreviewFile] = useState(null);
const { isShow, onCancel, onOk, show, message } = useModal();
const {
openSnackGlobal,
setOpenSnackGlobal,
infoSnackCustom,
setInfoSnackCustom,
} = useContext(MyContext);
const { isShow, onCancel, onOk, show, message } = useModal();
const {
openSnackGlobal,
setOpenSnackGlobal,
infoSnackCustom,
setInfoSnackCustom,
} = useContext(MyContext);
const handleSelectFile = async (existingFilePath) => {
const filePath = existingFilePath || (await window.electron.selectFile());
if (filePath) {
const content = await window.electron.readFile(filePath);
return { buffer: content, filePath };
} else {
console.log("No file selected.");
}
};
const handleSelectDirectry = async (existingDirectoryPath) => {
const { buffer, directoryPath } =
await window.electron.selectAndZipDirectory(existingDirectoryPath);
if (buffer) {
return { buffer, directoryPath };
} else {
console.log("No file selected.");
}
};
const handleSelectFile = async (existingFilePath) => {
const filePath = existingFilePath || await window.electron.selectFile();
if (filePath) {
const content = await window.electron.readFile(filePath);
return {buffer: content, filePath}
} else {
console.log('No file selected.');
}
};
const handleSelectDirectry = async (existingDirectoryPath) => {
const {buffer, directoryPath} = await window.electron.selectAndZipDirectory(existingDirectoryPath);
if (buffer) {
return {buffer, directoryPath}
} else {
console.log('No file selected.');
}
};
const addDevModeApp = async () => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
const addDevModeApp = async () => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
return;
}
const {portVal, domainVal} = await show({
message: "",
publishFee: "",
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
const framework = domainVal + ":" + portVal;
const response = await fetch(
`${getBaseApiReact()}/developer/proxy/start`,
{
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: framework,
}
);
const responseData = await response.text();
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:" + responseData,
return;
}
const { portVal, domainVal } = await show({
message: "",
publishFee: "",
});
const framework = domainVal + ":" + portVal;
const response = await fetch(
`${getBaseApiReact()}/developer/proxy/start`,
{
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: framework,
}
);
const responseData = await response.text();
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:" + responseData,
},
});
} catch (error) {}
};
const addPreviewApp = async (isRefresh, existingFilePath, tabId) => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
} catch (error) {}
};
return;
}
if (!myName) {
setOpenSnackGlobal(true);
const addPreviewApp = async (isRefresh, existingFilePath, tabId) => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message: "You need a name to use preview",
});
return;
}
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
return;
}
if (!myName) {
setOpenSnackGlobal(true);
const { buffer, filePath } = await handleSelectFile(existingFilePath);
setInfoSnackCustom({
type: "error",
message:
"You need a name to use preview",
});
return;
}
if (!buffer) {
setOpenSnackGlobal(true);
const {buffer, filePath} = await handleSelectFile(existingFilePath)
if (!buffer) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message: "Please select a file",
});
return;
}
const postBody = Buffer.from(buffer).toString("base64");
setInfoSnackCustom({
type: "error",
message:
"Please select a file",
});
return;
}
const postBody = Buffer.from(buffer).toString('base64')
const endpoint = await createEndpoint(`/arbitrary/APP/${myName}/zip?preview=true`)
const response = await fetch(
endpoint
,
{
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: postBody,
}
);
if(!response?.ok) throw new Error('Invalid zip')
const previewPath = await response.text();
if(tabId){
const endpoint = await createEndpoint(
`/arbitrary/APP/${myName}/zip?preview=true`
);
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: postBody,
});
if (!response?.ok) throw new Error("Invalid zip");
const previewPath = await response.text();
if (tabId) {
executeEvent("appsDevModeUpdateTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
filePath,
refreshFunc: (tabId)=> {
addPreviewApp(true, filePath, tabId)
refreshFunc: (tabId) => {
addPreviewApp(true, filePath, tabId);
},
tabId
tabId,
},
});
return
return;
}
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
filePath,
refreshFunc: (tabId)=> {
addPreviewApp(true, filePath, tabId)
}
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
filePath,
refreshFunc: (tabId) => {
addPreviewApp(true, filePath, tabId);
},
},
});
} catch (error) {
console.error(error);
}
};
const addPreviewAppWithDirectory = async (isRefresh, existingDir, tabId) => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
} catch (error) {
console.error(error)
return;
}
};
if (!myName) {
setOpenSnackGlobal(true);
const addPreviewAppWithDirectory = async (isRefresh, existingDir, tabId) => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message: "You need a name to use preview",
});
return;
}
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
return;
}
if (!myName) {
setOpenSnackGlobal(true);
const { buffer, directoryPath } = await handleSelectDirectry(existingDir);
setInfoSnackCustom({
type: "error",
message:
"You need a name to use preview",
});
return;
}
if (!buffer) {
setOpenSnackGlobal(true);
const {buffer, directoryPath} = await handleSelectDirectry(existingDir)
if (!buffer) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message: "Please select a file",
});
return;
}
const postBody = Buffer.from(buffer).toString("base64");
setInfoSnackCustom({
type: "error",
message:
"Please select a file",
});
return;
}
const postBody = Buffer.from(buffer).toString('base64')
const endpoint = await createEndpoint(`/arbitrary/APP/${myName}/zip?preview=true`)
const response = await fetch(
endpoint
,
{
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: postBody,
}
);
if(!response?.ok) throw new Error('Invalid zip')
const previewPath = await response.text();
if(tabId){
const endpoint = await createEndpoint(
`/arbitrary/APP/${myName}/zip?preview=true`
);
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: postBody,
});
if (!response?.ok) throw new Error("Invalid zip");
const previewPath = await response.text();
if (tabId) {
executeEvent("appsDevModeUpdateTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
directoryPath,
refreshFunc: (tabId)=> {
addPreviewAppWithDirectory(true, directoryPath, tabId)
refreshFunc: (tabId) => {
addPreviewAppWithDirectory(true, directoryPath, tabId);
},
tabId
tabId,
},
});
return
return;
}
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
directoryPath,
refreshFunc: (tabId)=> {
addPreviewAppWithDirectory(true, directoryPath, tabId)
}
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:12391" + previewPath,
isPreview: true,
directoryPath,
refreshFunc: (tabId) => {
addPreviewAppWithDirectory(true, directoryPath, tabId);
},
});
} catch (error) {
console.error(error)
}
};
},
});
} catch (error) {
console.error(error);
}
};
return (
<>
<AppsContainer
@@ -342,67 +332,146 @@ export const AppsDevModeHome = ({
<AppCircleLabel>Directory</AppCircleLabel>
</AppCircleContainer>
</ButtonBase>
<ButtonBase
onClick={() => {
executeEvent("appsDevModeAddTab", {
data: {
service: "APP",
name: "Q-Sandbox",
tabId: uid.rnd(),
},
});
}}
>
<AppCircleContainer
sx={{
gap: !isMobile ? "10px" : "5px",
}}
>
<AppCircle>
<Avatar
sx={{
height: "42px",
width: "42px",
"& img": {
objectFit: "fill",
},
}}
alt="Q-Sandbox"
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/Q-Sandbox/qortal_avatar?async=true`}
>
<img
style={{
width: "31px",
height: "auto",
}}
alt="center-icon"
/>
</Avatar>
</AppCircle>
<AppCircleLabel>Q-Sandbox</AppCircleLabel>
</AppCircleContainer>
</ButtonBase>
<ButtonBase
onClick={() => {
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:12391",
isPreview: false,
customIcon: swaggerSVG
},
});
}}
>
<AppCircleContainer
sx={{
gap: !isMobile ? "10px" : "5px",
}}
>
<AppCircle>
<Avatar
sx={{
height: "42px",
width: "42px",
"& img": {
objectFit: "fill",
},
}}
alt="API"
src={swaggerSVG}
>
<img
style={{
width: "31px",
height: "auto",
}}
alt="center-icon"
/>
</Avatar>
</AppCircle>
<AppCircleLabel>API</AppCircleLabel>
</AppCircleContainer>
</ButtonBase>
</AppsContainer>
{isShow && (
<Dialog
open={isShow}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
onKeyDown={(e) => {
if (e.key === 'Enter' && domain && port) {
onOk({ portVal: port, domainVal: domain });
}
}}
>
<DialogTitle id="alert-dialog-title">
{"Add custom framework"}
</DialogTitle>
<DialogContent>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
}}
>
<Label>Domain</Label>
<Input
placeholder="Domain"
value={domain}
onChange={(e) => setDomain(e.target.value)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
marginTop: '15px'
}}
>
<Label>Port</Label>
<Input
placeholder="Port"
value={port}
onChange={(e) => setPort(e.target.value)}
/>
</Box>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCancel}>
Close
</Button>
<Button
disabled={!domain || !port}
variant="contained"
onClick={() => onOk({ portVal: port, domainVal: domain })}
autoFocus
>
Add
</Button>
</DialogActions>
</Dialog>
<Dialog
open={isShow}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
onKeyDown={(e) => {
if (e.key === "Enter" && domain && port) {
onOk({ portVal: port, domainVal: domain });
}
}}
>
<DialogTitle id="alert-dialog-title">
{"Add custom framework"}
</DialogTitle>
<DialogContent>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
}}
>
<Label>Domain</Label>
<Input
placeholder="Domain"
value={domain}
onChange={(e) => setDomain(e.target.value)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
marginTop: "15px",
}}
>
<Label>Port</Label>
<Input
placeholder="Port"
value={port}
onChange={(e) => setPort(e.target.value)}
/>
</Box>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCancel}>
Close
</Button>
<Button
disabled={!domain || !port}
variant="contained"
onClick={() => onOk({ portVal: port, domainVal: domain })}
autoFocus
>
Add
</Button>
</DialogActions>
</Dialog>
)}
</>
);

View File

@@ -1,59 +1,67 @@
import React from 'react'
import { TabParent } from './Apps-styles'
import React from "react";
import { TabParent } from "./Apps-styles";
import NavCloseTab from "../../assets/svgs/NavCloseTab.svg";
import { getBaseApiReact } from '../../App';
import { Avatar, ButtonBase } from '@mui/material';
import { getBaseApiReact } from "../../App";
import { Avatar, ButtonBase } from "@mui/material";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from '../../utils/events';
import { executeEvent } from "../../utils/events";
export const AppsDevModeTabComponent = ({isSelected, app}) => {
export const AppsDevModeTabComponent = ({ isSelected, app }) => {
return (
<ButtonBase onClick={()=> {
if(isSelected){
executeEvent('removeTabDevMode', {
data: app
})
return
}
executeEvent('setSelectedTabDevMode', {
<ButtonBase
onClick={() => {
if (isSelected) {
executeEvent("removeTabDevMode", {
data: app,
isDevMode: true
})
}}>
<TabParent sx={{
border: isSelected && '1px solid #FFFFFF'
}}>
});
return;
}
executeEvent("setSelectedTabDevMode", {
data: app,
isDevMode: true,
});
}}
>
<TabParent
sx={{
border: isSelected && "1px solid #FFFFFF",
}}
>
{isSelected && (
<img style={
{
position: 'absolute',
top: '-5px',
right: '-5px',
zIndex: 1
}
} src={NavCloseTab}/>
) }
<Avatar
sx={{
height: "28px",
width: "28px",
}}
alt=''
src={``}
>
<img
style={{
width: "28px",
height: "auto",
}}
src={LogoSelected}
alt="center-icon"
/>
</Avatar>
</TabParent>
<img
style={{
position: "absolute",
top: "-5px",
right: "-5px",
zIndex: 1,
}}
src={NavCloseTab}
/>
)}
<Avatar
sx={{
height: "28px",
width: "28px",
}}
alt=""
src={``}
>
<img
style={{
width: "28px",
height: "auto",
}}
src={ app?.customIcon ? app?.customIcon :
app?.service
? `${getBaseApiReact()}/arbitrary/THUMBNAIL/${
app?.name
}/qortal_avatar?async=true`
: LogoSelected
}
alt="center-icon"
/>
</Avatar>
</TabParent>
</ButtonBase>
)
}
);
};