Q-Manager/src/actions/PUBLISH_QDN_RESOURCE.jsx

384 lines
11 KiB
JavaScript

import React, { useState } from "react";
import {
Box,
ButtonBase,
CircularProgress,
MenuItem,
Select,
Typography,
styled,
} from "@mui/material";
import { DisplayCode } from "../components/DisplayCode";
import { DisplayCodeResponse } from "../components/DisplayCodeResponse";
import ShortUniqueId from "short-unique-id";
import Button from "../components/Button";
import { useDropzone } from "react-dropzone";
import { privateServices, services } from "../constants";
import { fileToBase64 } from "../utils";
import toast from 'react-hot-toast';
import { openToast } from "../components/openToast";
const uid = new ShortUniqueId({ length: 10 });
export const Label = styled("label")(
({ theme }) => `
font-family: 'IBM Plex Sans', sans-serif;
font-size: 14px;
display: block;
margin-bottom: 4px;
font-weight: 400;
`
);
export const PUBLISH_QDN_RESOURCE = ({ addNodeByPath, myName, mode, existingFile, updateByPath , groups, selectedGroup}) => {
const [requestData, setRequestData] = useState({
service: existingFile?.service || mode === 'private' ? "DOCUMENT_PRIVATE" : "DOCUMENT"
});
const { getRootProps, getInputProps } = useDropzone({
maxFiles: 1,
onDrop: async (acceptedFiles) => {
const fileSelected = acceptedFiles[0];
if (fileSelected) {
setFile(fileSelected);
}
},
});
const [isLoading, setIsLoading] = useState(false);
const [file, setFile] = useState(null);
const executeQortalRequestGroup = async () => {
const promise = (async () => {
try {
if (!file) throw new Error('Please select a file')
if(!selectedGroup) throw new Error('Please select a group')
const findGroup = groups?.find((group)=> group.groupId === selectedGroup)
if(!findGroup) throw new Error('Cannot find group')
setIsLoading(true);
const fileExtension = file?.name?.includes(".") ? file.name.split(".").pop() : "";
const fileTitle =
file?.name
?.split(".")
.slice(0, -1)
.join(".")
.replace(/ /g, "_")
.slice(0, 20) || "Untitled";
const filename = fileExtension ? `${fileTitle}.${fileExtension}` : fileTitle;
const constructedIdentifier = existingFile?.identifier || `grp-q-manager-858-${uid.rnd()}`;
const base64File = await fileToBase64(file);
const encryptedData = await qortalRequest({
action: "ENCRYPT_QORTAL_GROUP_DATA",
data64: base64File,
groupId: selectedGroup
});
if(!encryptedData) throw new Error('Unable to encrypt data')
let account = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE",
service: existingFile?.service || requestData?.service,
identifier: constructedIdentifier,
data64: encryptedData,
externalEncrypt: true,
});
if (account?.identifier) {
if (!!existingFile) {
updateByPath({
...existingFile,
mimeType: file?.type,
});
setFile("");
return true; // Success
}
addNodeByPath(
undefined,
{
type: "file",
name: filename,
mimeType: file?.type,
qortalName: myName,
identifier: constructedIdentifier,
service: requestData?.service,
group: selectedGroup,
groupName: findGroup?.groupName
},
undefined
);
return true; // Success
} else {
throw new Error("Unable to publish the file");
}
} catch (error) {
console.error("Error:", error);
throw error; // Ensure the error is propagated to the toast
} finally {
setIsLoading(false);
}
})();
await openToast(promise, {
loading: "Publishing the file...",
success: "File published successfully!",
error: (err) => `Failed to publish: ${err?.error || err?.message || "An unknown error occurred"}`,
});
};
const executeQortalRequestPrivate = async () => {
const promise = (async () => {
try {
if (!file) return;
setIsLoading(true);
const fileExtension = file?.name?.includes(".") ? file.name.split(".").pop() : "";
const fileTitle =
file?.name
?.split(".")
.slice(0, -1)
.join(".")
.replace(/ /g, "_")
.slice(0, 20) || "Untitled";
const filename = fileExtension ? `${fileTitle}.${fileExtension}` : fileTitle;
const constructedIdentifier = existingFile?.identifier || `p-q-manager-858-${uid.rnd()}`;
const base64File = await fileToBase64(file);
const encryptedData = await qortalRequest({
action: "ENCRYPT_DATA_WITH_SHARING_KEY",
data64: base64File,
});
if(!encryptedData) throw new Error('Unable to encrypt data')
let account = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE",
service: existingFile?.service || requestData?.service,
identifier: constructedIdentifier,
data64: encryptedData,
});
if (account?.identifier) {
if (!!existingFile) {
updateByPath({
...existingFile,
mimeType: file?.type,
});
setFile("");
return true; // Success
}
addNodeByPath(
undefined,
{
type: "file",
name: filename,
mimeType: file?.type,
qortalName: myName,
identifier: constructedIdentifier,
service: requestData?.service,
},
undefined
);
return true; // Success
} else {
throw new Error("Unable to publish the file");
}
} catch (error) {
console.error("Error:", error);
throw error; // Ensure the error is propagated to the toast
} finally {
setIsLoading(false);
}
})();
await openToast(promise, {
loading: "Publishing the file...",
success: "File published successfully!",
error: (err) => `Failed to publish: ${err?.error || err?.message || "An unknown error occurred"}`,
});
};
const executeQortalRequest = async () => {
try {
setIsLoading(true);
const promise = (async () => {
const fileExtension = file?.name?.includes(".")
? file.name.split(".").pop()
: "";
const fileTitle =
file?.name
?.split(".")
.slice(0, -1)
.join(".")
.replace(/ /g, "_")
.slice(0, 20) || "Untitled";
const filename = fileExtension
? `${fileTitle}.${fileExtension}`
: fileTitle;
const constructedIdentifier =
existingFile?.identifier || `q-manager-858-${uid.rnd()}`;
const account = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE",
service: existingFile?.service || requestData?.service,
identifier: constructedIdentifier,
file,
filename,
});
if (account?.identifier) {
if (!!existingFile) {
updateByPath({
...existingFile,
mimeType: file?.type,
});
setFile("");
return;
}
addNodeByPath(
undefined,
{
type: "file",
name: filename,
mimeType: file?.type,
qortalName: myName,
identifier: constructedIdentifier,
service: requestData?.service,
},
undefined
);
if(!existingFile){
setFile(null)
}
return;
} else {
throw new Error("Unable to publish the file");
}
})();
await openToast(promise, {
loading: "Publishing the file...",
success: "File published successfully!",
error: (err) => `Failed to publish: ${err.error || err.message || err}`,
});
} catch (error) {
console.error("Error during publishing:", error);
} finally {
setIsLoading(false);
}
};
return (
<div
style={{
padding: "10px",
}}
>
<div
className="card"
style={{
background: "rgba(0, 0, 0, 0.1)",
}}
>
<div className="message-row">
<Label>Service</Label>
<Select
disabled={!!existingFile}
size="small"
labelId="label-select-category"
id="id-select-category"
value={requestData?.service}
displayEmpty
onChange={(e) =>
setRequestData((prev) => {
return {
...prev,
service: e.target.value,
};
})
}
sx={{
width: "300px",
}}
MenuProps={{
PaperProps: {
sx: {
backgroundColor: "#333333", // Background of the dropdown
color: "#ffffff", // Text color
},
},
}}
>
<MenuItem value={0}>
<em>No service selected</em>
</MenuItem>
{(mode === 'private' ? privateServices : services)?.map((service) => {
return (
<MenuItem key={service.name} value={service.name}>
{`${service.name} - max ${service.sizeLabel}`}
</MenuItem>
);
})}
</Select>
<button
{...getRootProps()}
style={{
width: "150px",
}}
>
<input {...getInputProps()} />
Select file
</button>
<Typography>{file?.name}</Typography>
{file && (
<Button
name="Remove file"
bgColor="pink"
onClick={() => {
setFile(null);
}}
>
Remove file
</Button>
)}
<Button
name={!!existingFile ? "Edit Publish" :"Publish"}
bgColor="#309ed1"
onClick={()=> {
if(mode ==='group'){
executeQortalRequestGroup()
}
else if(mode === 'private'){
executeQortalRequestPrivate()
} else {
executeQortalRequest()
}
}}
/>
</div>
</div>
</div>
);
};