mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-28 22:07:52 +00:00
added private app name and logo
This commit is contained in:
parent
16b7ed2dbc
commit
76eb315b9d
@ -9,7 +9,7 @@ import {
|
|||||||
PublishQAppChoseFile,
|
PublishQAppChoseFile,
|
||||||
PublishQAppInfo,
|
PublishQAppInfo,
|
||||||
} from "./Apps-styles";
|
} from "./Apps-styles";
|
||||||
import { Avatar, Box, Button, ButtonBase, Dialog, DialogActions, DialogContent, DialogTitle, Input, MenuItem, Select, Tab, Tabs } from "@mui/material";
|
import { Avatar, Box, Button, ButtonBase, Dialog, DialogActions, DialogContent, DialogTitle, Input, MenuItem, Select, Tab, Tabs, Typography } from "@mui/material";
|
||||||
import { Add } from "@mui/icons-material";
|
import { Add } from "@mui/icons-material";
|
||||||
import { getBaseApiReact, isMobile, MyContext } from "../../App";
|
import { getBaseApiReact, isMobile, MyContext } from "../../App";
|
||||||
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||||
@ -25,6 +25,9 @@ import { saveToLocalStorage } from "./AppsNavBarDesktop";
|
|||||||
import { Label } from "../Group/AddGroup";
|
import { Label } from "../Group/AddGroup";
|
||||||
import { useHandlePrivateApps } from "./useHandlePrivateApps";
|
import { useHandlePrivateApps } from "./useHandlePrivateApps";
|
||||||
import { useDropzone } from "react-dropzone";
|
import { useDropzone } from "react-dropzone";
|
||||||
|
import ImageUploader from "../../common/ImageUploader";
|
||||||
|
import { base64ToBlobUrl, fileToBase64 } from "../../utils/fileReading";
|
||||||
|
import { objectToBase64 } from "../../qdn/encryption/group-encryption";
|
||||||
|
|
||||||
const maxFileSize = 50 * 1024 * 1024 ; // 50MB or 400MB
|
const maxFileSize = 50 * 1024 * 1024 ; // 50MB or 400MB
|
||||||
|
|
||||||
@ -37,6 +40,7 @@ export const AppsHomeDesktop = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const {openApp} = useHandlePrivateApps()
|
const {openApp} = useHandlePrivateApps()
|
||||||
const [file, setFile] = useState(null)
|
const [file, setFile] = useState(null)
|
||||||
|
const [logo, setLogo] = useState(null)
|
||||||
const { getRootProps, getInputProps } = useDropzone({
|
const { getRootProps, getInputProps } = useDropzone({
|
||||||
accept: {
|
accept: {
|
||||||
"application/zip": [".zip"], // Only accept zip files
|
"application/zip": [".zip"], // Only accept zip files
|
||||||
@ -91,7 +95,8 @@ const [myGroupsWhereIAmAdmin, setMyGroupsWhereIAmAdmin] = useRecoilState(
|
|||||||
|
|
||||||
const [newPrivateAppValues, setNewPrivateAppValues] = useState({
|
const [newPrivateAppValues, setNewPrivateAppValues] = useState({
|
||||||
service: 'DOCUMENT',
|
service: 'DOCUMENT',
|
||||||
identifier: ''
|
identifier: '',
|
||||||
|
name: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
const addPrivateApp = async ()=> {
|
const addPrivateApp = async ()=> {
|
||||||
@ -114,23 +119,35 @@ const [myGroupsWhereIAmAdmin, setMyGroupsWhereIAmAdmin] = useRecoilState(
|
|||||||
})
|
})
|
||||||
setNewPrivateAppValues({
|
setNewPrivateAppValues({
|
||||||
service: 'DOCUMENT',
|
service: 'DOCUMENT',
|
||||||
identifier: ''
|
identifier: '',
|
||||||
|
name: ''
|
||||||
})
|
})
|
||||||
setFile(null)
|
setFile(null)
|
||||||
setValueTabPrivateApp(0)
|
setValueTabPrivateApp(0)
|
||||||
setSelectedGroup(null)
|
setSelectedGroup(0)
|
||||||
|
setLogo(null)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishPrivateApp = async ()=> {
|
const publishPrivateApp = async ()=> {
|
||||||
try {
|
try {
|
||||||
if(selectedGroup === 0) return
|
if(selectedGroup === 0) return
|
||||||
|
if(!logo) throw new Error('Please select an image for a logo')
|
||||||
if(!myName) throw new Error('You need a Qortal name to publish')
|
if(!myName) throw new Error('You need a Qortal name to publish')
|
||||||
|
if(!newPrivateAppValues?.name) throw new Error('Your app needs a name')
|
||||||
|
const base64Logo = await fileToBase64(logo)
|
||||||
|
const base64App = await fileToBase64(file)
|
||||||
|
const objectToSave = {
|
||||||
|
app: base64App,
|
||||||
|
logo: base64Logo,
|
||||||
|
name: newPrivateAppValues.name
|
||||||
|
}
|
||||||
|
const object64 = await objectToBase64(objectToSave);
|
||||||
const decryptedData = await window.sendMessage(
|
const decryptedData = await window.sendMessage(
|
||||||
"ENCRYPT_QORTAL_GROUP_DATA",
|
"ENCRYPT_QORTAL_GROUP_DATA",
|
||||||
|
|
||||||
{
|
{
|
||||||
file: file,
|
base64: object64,
|
||||||
groupId: selectedGroup,
|
groupId: selectedGroup,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -598,6 +615,35 @@ service: 'DOCUMENT',
|
|||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Spacer height="10px"/>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "5px",
|
||||||
|
marginTop: "15px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Label>App name</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="App name"
|
||||||
|
value={newPrivateAppValues?.name}
|
||||||
|
onChange={(e) => setNewPrivateAppValues((prev)=> {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
name: e.target.value
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Spacer height="10px" />
|
||||||
|
<ImageUploader onPick={(file) => setLogo(file)}>
|
||||||
|
<Button variant="contained">Choose logo</Button>
|
||||||
|
</ImageUploader>
|
||||||
|
{logo?.name}
|
||||||
|
<Spacer height="25px" />
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button variant="contained" onClick={()=> {
|
<Button variant="contained" onClick={()=> {
|
||||||
|
@ -58,7 +58,7 @@ const SortableItem = ({ id, name, app, isDesktop }) => {
|
|||||||
border: "none",
|
border: "none",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{app?.isPrivate ? (
|
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
|
||||||
<LockIcon
|
<LockIcon
|
||||||
sx={{
|
sx={{
|
||||||
height: "42px",
|
height: "42px",
|
||||||
@ -75,7 +75,7 @@ const SortableItem = ({ id, name, app, isDesktop }) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
alt={app?.metadata?.title || app?.name}
|
alt={app?.metadata?.title || app?.name}
|
||||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
src={ app?.privateAppProperties?.logo ? app?.privateAppProperties?.logo :`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||||
app?.name
|
app?.name
|
||||||
}/qortal_avatar?async=true`}
|
}/qortal_avatar?async=true`}
|
||||||
>
|
>
|
||||||
@ -93,7 +93,7 @@ const SortableItem = ({ id, name, app, isDesktop }) => {
|
|||||||
</AppCircle>
|
</AppCircle>
|
||||||
{app?.isPrivate ? (
|
{app?.isPrivate ? (
|
||||||
<AppCircleLabel>
|
<AppCircleLabel>
|
||||||
Private
|
{`${app?.privateAppProperties?.appName || "Private"}`}
|
||||||
</AppCircleLabel>
|
</AppCircleLabel>
|
||||||
) : (
|
) : (
|
||||||
<AppCircleLabel>
|
<AppCircleLabel>
|
||||||
|
@ -37,7 +37,7 @@ const TabComponent = ({ isSelected, app }) => {
|
|||||||
src={NavCloseTab}
|
src={NavCloseTab}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{app?.isPrivate ? (
|
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
|
||||||
<LockIcon
|
<LockIcon
|
||||||
sx={{
|
sx={{
|
||||||
height: "28px",
|
height: "28px",
|
||||||
@ -51,7 +51,7 @@ const TabComponent = ({ isSelected, app }) => {
|
|||||||
width: "28px",
|
width: "28px",
|
||||||
}}
|
}}
|
||||||
alt={app?.name}
|
alt={app?.name}
|
||||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
src={app?.privateAppProperties?.logo ? app?.privateAppProperties?.logo :`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||||
app?.name
|
app?.name
|
||||||
}/qortal_avatar?async=true`}
|
}/qortal_avatar?async=true`}
|
||||||
>
|
>
|
||||||
|
@ -8,6 +8,9 @@ import {
|
|||||||
sortablePinnedAppsAtom,
|
sortablePinnedAppsAtom,
|
||||||
} from "../../atoms/global";
|
} from "../../atoms/global";
|
||||||
import { saveToLocalStorage } from "./AppsNavBarDesktop";
|
import { saveToLocalStorage } from "./AppsNavBarDesktop";
|
||||||
|
import { base64ToBlobUrl } from "../../utils/fileReading";
|
||||||
|
import { base64ToUint8Array } from "../../qdn/encryption/group-encryption";
|
||||||
|
import { uint8ArrayToObject } from "../../backgroundFunctions/encryption";
|
||||||
|
|
||||||
export const useHandlePrivateApps = () => {
|
export const useHandlePrivateApps = () => {
|
||||||
const [status, setStatus] = useState("");
|
const [status, setStatus] = useState("");
|
||||||
@ -58,6 +61,10 @@ export const useHandlePrivateApps = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if(decryptedData?.error) throw new Error(decryptedData?.error)
|
if(decryptedData?.error) throw new Error(decryptedData?.error)
|
||||||
|
|
||||||
|
const convertToUint = base64ToUint8Array(decryptedData)
|
||||||
|
const UintToObject = uint8ArrayToObject(convertToUint)
|
||||||
|
|
||||||
if (decryptedData) {
|
if (decryptedData) {
|
||||||
setInfoSnackCustom({
|
setInfoSnackCustom({
|
||||||
type: "info",
|
type: "info",
|
||||||
@ -71,7 +78,7 @@ export const useHandlePrivateApps = () => {
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "text/plain",
|
"Content-Type": "text/plain",
|
||||||
},
|
},
|
||||||
body: decryptedData,
|
body: UintToObject?.app,
|
||||||
});
|
});
|
||||||
const previewPath = await response.text();
|
const previewPath = await response.text();
|
||||||
setOpenSnackGlobal(false);
|
setOpenSnackGlobal(false);
|
||||||
@ -81,12 +88,15 @@ export const useHandlePrivateApps = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const appName = UintToObject?.name
|
||||||
|
const logo = UintToObject?.logo ? `data:image/png;base64,${UintToObject?.logo}` : null
|
||||||
|
|
||||||
executeEvent("addTab", {
|
executeEvent("addTab", {
|
||||||
data: {
|
data: {
|
||||||
url: await createEndpoint(previewPath),
|
url: await createEndpoint(previewPath),
|
||||||
isPreview: true,
|
isPreview: true,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
privateAppProperties: { ...privateAppProperties },
|
privateAppProperties: { ...privateAppProperties, logo, appName },
|
||||||
filePath: "",
|
filePath: "",
|
||||||
refreshFunc: (tabId) => {
|
refreshFunc: (tabId) => {
|
||||||
refreshfunc(tabId);
|
refreshfunc(tabId);
|
||||||
@ -101,7 +111,7 @@ export const useHandlePrivateApps = () => {
|
|||||||
{
|
{
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
isPreview: true,
|
isPreview: true,
|
||||||
privateAppProperties: { ...privateAppProperties },
|
privateAppProperties: { ...privateAppProperties, logo, appName },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user