mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-17 21:31:22 +00:00
Move tsx into proper folder
This commit is contained in:
parent
6dea8e2468
commit
d0cfc4db2f
@ -34,9 +34,9 @@ import ltcLogo from './assets/ltc.png';
|
|||||||
import PersonSearchIcon from '@mui/icons-material/PersonSearch';
|
import PersonSearchIcon from '@mui/icons-material/PersonSearch';
|
||||||
import qortLogo from './assets/qort.png';
|
import qortLogo from './assets/qort.png';
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
import { Download } from './assets/svgs/Download.tsx';
|
import { Download } from './assets/Icons/Download.tsx';
|
||||||
import { Logout } from './assets/svgs/Logout.tsx';
|
import { Logout } from './assets/Icons/Logout.tsx';
|
||||||
import { Return } from './assets/svgs/Return.tsx';
|
import { Return } from './assets/Icons/Return.tsx';
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import Success from './assets/svgs/Success.svg';
|
import Success from './assets/svgs/Success.svg';
|
||||||
import './utils/seedPhrase/RandomSentenceGenerator';
|
import './utils/seedPhrase/RandomSentenceGenerator';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useTheme } from '@mui/material';
|
import { useTheme } from '@mui/material';
|
||||||
import { SVGProps } from '../svgs/interfaces';
|
import { SVGProps } from './interfaces';
|
||||||
|
|
||||||
export const WalletIcon: React.FC<SVGProps> = ({
|
export const WalletIcon: React.FC<SVGProps> = ({
|
||||||
color,
|
color,
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8047 0.393196V7.21185H16.3036L10.0003 13.5139L3.69697 7.21185H7.19584V0H12.8045L12.8047 0.393196ZM2.7047 16.8587V13.9861H0V18.6179C0 19.3774 0.622589 20 1.38213 20H18.6179C19.3774 20 20 19.3774 20 18.6179V13.9861H17.2962V17.2963L2.70461 17.2954L2.7047 16.8587Z" fill="white" fill-opacity="0.5"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 452 B |
@ -1,20 +1,14 @@
|
|||||||
import { Box, Rating, Typography } from "@mui/material";
|
import { Box, Rating } from '@mui/material';
|
||||||
import React, {
|
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
useCallback,
|
import { getFee } from '../../background';
|
||||||
useContext,
|
import { MyContext, getBaseApiReact } from '../../App';
|
||||||
useEffect,
|
import { CustomizedSnackbars } from '../Snackbar/Snackbar';
|
||||||
useRef,
|
import { StarFilledIcon } from '../../assets/Icons/StarFilled';
|
||||||
useState,
|
import { StarEmptyIcon } from '../../assets/Icons/StarEmpty';
|
||||||
} from "react";
|
import { AppInfoUserName } from './Apps-styles';
|
||||||
import { getFee } from "../../background";
|
import { Spacer } from '../../common/Spacer';
|
||||||
import { MyContext, getBaseApiReact } from "../../App";
|
|
||||||
import { CustomizedSnackbars } from "../Snackbar/Snackbar";
|
|
||||||
import { StarFilledIcon } from "../../assets/svgs/StarFilled";
|
|
||||||
import { StarEmptyIcon } from "../../assets/svgs/StarEmpty";
|
|
||||||
import { AppInfoUserName } from "./Apps-styles";
|
|
||||||
import { Spacer } from "../../common/Spacer";
|
|
||||||
|
|
||||||
export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
export const AppRating = ({ app, myName, ratingCountPosition = 'right' }) => {
|
||||||
const [value, setValue] = useState(0);
|
const [value, setValue] = useState(0);
|
||||||
const { show } = useContext(MyContext);
|
const { show } = useContext(MyContext);
|
||||||
const [hasPublishedRating, setHasPublishedRating] = useState<null | boolean>(
|
const [hasPublishedRating, setHasPublishedRating] = useState<null | boolean>(
|
||||||
@ -33,14 +27,14 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
const url = `${getBaseApiReact()}/polls/${pollName}`;
|
const url = `${getBaseApiReact()}/polls/${pollName}`;
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
if (responseData?.message?.includes("POLL_NO_EXISTS")) {
|
if (responseData?.message?.includes('POLL_NO_EXISTS')) {
|
||||||
setHasPublishedRating(false);
|
setHasPublishedRating(false);
|
||||||
} else if (responseData?.pollName) {
|
} else if (responseData?.pollName) {
|
||||||
setPollInfo(responseData);
|
setPollInfo(responseData);
|
||||||
@ -48,9 +42,9 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
const urlVotes = `${getBaseApiReact()}/polls/votes/${pollName}`;
|
const urlVotes = `${getBaseApiReact()}/polls/votes/${pollName}`;
|
||||||
|
|
||||||
const responseVotes = await fetch(urlVotes, {
|
const responseVotes = await fetch(urlVotes, {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -59,15 +53,15 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
const voteCount = responseDataVotes.voteCounts;
|
const voteCount = responseDataVotes.voteCounts;
|
||||||
// Include initial value vote in the calculation
|
// Include initial value vote in the calculation
|
||||||
const ratingVotes = voteCount.filter(
|
const ratingVotes = voteCount.filter(
|
||||||
(vote) => !vote.optionName.startsWith("initialValue-")
|
(vote) => !vote.optionName.startsWith('initialValue-')
|
||||||
);
|
);
|
||||||
const initialValueVote = voteCount.find((vote) =>
|
const initialValueVote = voteCount.find((vote) =>
|
||||||
vote.optionName.startsWith("initialValue-")
|
vote.optionName.startsWith('initialValue-')
|
||||||
);
|
);
|
||||||
if (initialValueVote) {
|
if (initialValueVote) {
|
||||||
// Convert "initialValue-X" to just "X" and add it to the ratingVotes array
|
// Convert "initialValue-X" to just "X" and add it to the ratingVotes array
|
||||||
const initialRating = parseInt(
|
const initialRating = parseInt(
|
||||||
initialValueVote.optionName.split("-")[1],
|
initialValueVote.optionName.split('-')[1],
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
ratingVotes.push({
|
ratingVotes.push({
|
||||||
@ -92,7 +86,7 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
setValue(averageRating);
|
setValue(averageRating);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.message?.includes("POLL_NO_EXISTS")) {
|
if (error?.message?.includes('POLL_NO_EXISTS')) {
|
||||||
setHasPublishedRating(false);
|
setHasPublishedRating(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,45 +99,47 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
|
|
||||||
const rateFunc = async (event, chosenValue, currentValue) => {
|
const rateFunc = async (event, chosenValue, currentValue) => {
|
||||||
try {
|
try {
|
||||||
const newValue = chosenValue || currentValue
|
const newValue = chosenValue || currentValue;
|
||||||
if (!myName) throw new Error("You need a name to rate.");
|
if (!myName) throw new Error('You need a name to rate.');
|
||||||
if (!app?.name) return;
|
if (!app?.name) return;
|
||||||
const fee = await getFee("CREATE_POLL");
|
const fee = await getFee('CREATE_POLL');
|
||||||
|
|
||||||
await show({
|
await show({
|
||||||
message: `Would you like to rate this app a rating of ${newValue}?. It will create a POLL tx.`,
|
message: `Would you like to rate this app a rating of ${newValue}?. It will create a POLL tx.`,
|
||||||
publishFee: fee.fee + " QORT",
|
publishFee: fee.fee + ' QORT',
|
||||||
});
|
});
|
||||||
if (hasPublishedRating === false) {
|
if (hasPublishedRating === false) {
|
||||||
const pollName = `app-library-${app.service}-rating-${app.name}`;
|
const pollName = `app-library-${app.service}-rating-${app.name}`;
|
||||||
const pollOptions = [`1, 2, 3, 4, 5, initialValue-${newValue}`];
|
const pollOptions = [`1, 2, 3, 4, 5, initialValue-${newValue}`];
|
||||||
await new Promise((res, rej) => {
|
await new Promise((res, rej) => {
|
||||||
window.sendMessage("createPoll", {
|
window
|
||||||
|
.sendMessage(
|
||||||
pollName: pollName,
|
'createPoll',
|
||||||
pollDescription: `Rating for ${app.service} ${app.name}`,
|
{
|
||||||
pollOptions: pollOptions,
|
pollName: pollName,
|
||||||
pollOwnerAddress: myName,
|
pollDescription: `Rating for ${app.service} ${app.name}`,
|
||||||
|
pollOptions: pollOptions,
|
||||||
}, 60000)
|
pollOwnerAddress: myName,
|
||||||
.then((response) => {
|
},
|
||||||
if (response.error) {
|
60000
|
||||||
rej(response?.message);
|
)
|
||||||
return;
|
.then((response) => {
|
||||||
} else {
|
if (response.error) {
|
||||||
res(response);
|
rej(response?.message);
|
||||||
setInfoSnack({
|
return;
|
||||||
type: "success",
|
} else {
|
||||||
message:
|
res(response);
|
||||||
"Successfully rated. Please wait a couple minutes for the network to propogate the changes.",
|
setInfoSnack({
|
||||||
});
|
type: 'success',
|
||||||
setOpenSnack(true);
|
message:
|
||||||
}
|
'Successfully rated. Please wait a couple minutes for the network to propogate the changes.',
|
||||||
})
|
});
|
||||||
.catch((error) => {
|
setOpenSnack(true);
|
||||||
console.error("Failed qortalRequest", error);
|
}
|
||||||
});
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed qortalRequest', error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const pollName = `app-library-${app.service}-rating-${app.name}`;
|
const pollName = `app-library-${app.service}-rating-${app.name}`;
|
||||||
@ -152,39 +148,41 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
(option) => +option.optionName === +newValue
|
(option) => +option.optionName === +newValue
|
||||||
);
|
);
|
||||||
if (isNaN(optionIndex) || optionIndex === -1)
|
if (isNaN(optionIndex) || optionIndex === -1)
|
||||||
throw new Error("Cannot find rating option");
|
throw new Error('Cannot find rating option');
|
||||||
await new Promise((res, rej) => {
|
await new Promise((res, rej) => {
|
||||||
window.sendMessage("voteOnPoll", {
|
window
|
||||||
|
.sendMessage(
|
||||||
pollName: pollName,
|
'voteOnPoll',
|
||||||
optionIndex,
|
{
|
||||||
|
pollName: pollName,
|
||||||
}, 60000)
|
optionIndex,
|
||||||
.then((response) => {
|
},
|
||||||
if (response.error) {
|
60000
|
||||||
rej(response?.message);
|
)
|
||||||
return;
|
.then((response) => {
|
||||||
} else {
|
if (response.error) {
|
||||||
res(response);
|
rej(response?.message);
|
||||||
setInfoSnack({
|
return;
|
||||||
type: "success",
|
} else {
|
||||||
message:
|
res(response);
|
||||||
"Successfully rated. Please wait a couple minutes for the network to propogate the changes.",
|
setInfoSnack({
|
||||||
});
|
type: 'success',
|
||||||
setOpenSnack(true);
|
message:
|
||||||
}
|
'Successfully rated. Please wait a couple minutes for the network to propogate the changes.',
|
||||||
})
|
});
|
||||||
.catch((error) => {
|
setOpenSnack(true);
|
||||||
console.error("Failed qortalRequest", error);
|
}
|
||||||
});
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed qortalRequest', error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', error)
|
console.log('error', error);
|
||||||
setInfoSnack({
|
setInfoSnack({
|
||||||
type: "error",
|
type: 'error',
|
||||||
message: error?.message || "Unable to rate",
|
message: error?.message || 'Unable to rate',
|
||||||
});
|
});
|
||||||
setOpenSnack(true);
|
setOpenSnack(true);
|
||||||
}
|
}
|
||||||
@ -194,17 +192,17 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
<div>
|
<div>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
flexDirection: ratingCountPosition === "top" ? "column" : "row",
|
flexDirection: ratingCountPosition === 'top' ? 'column' : 'row',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ratingCountPosition === "top" && (
|
{ratingCountPosition === 'top' && (
|
||||||
<>
|
<>
|
||||||
<AppInfoUserName>
|
<AppInfoUserName>
|
||||||
{(votesInfo?.totalVotes ?? 0) +
|
{(votesInfo?.totalVotes ?? 0) +
|
||||||
(votesInfo?.voteCounts?.length === 6 ? 1 : 0)}{" "}
|
(votesInfo?.voteCounts?.length === 6 ? 1 : 0)}{' '}
|
||||||
{" RATINGS"}
|
{' RATINGS'}
|
||||||
</AppInfoUserName>
|
</AppInfoUserName>
|
||||||
<Spacer height="6px" />
|
<Spacer height="6px" />
|
||||||
<AppInfoUserName>{value?.toFixed(1)}</AppInfoUserName>
|
<AppInfoUserName>{value?.toFixed(1)}</AppInfoUserName>
|
||||||
@ -214,17 +212,17 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
|
|
||||||
<Rating
|
<Rating
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(event, rating)=> rateFunc(event, rating, value)}
|
onChange={(event, rating) => rateFunc(event, rating, value)}
|
||||||
precision={1}
|
precision={1}
|
||||||
size="small"
|
size="small"
|
||||||
icon={<StarFilledIcon />}
|
icon={<StarFilledIcon />}
|
||||||
emptyIcon={<StarEmptyIcon />}
|
emptyIcon={<StarEmptyIcon />}
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
gap: "2px",
|
gap: '2px',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{ratingCountPosition === "right" && (
|
{ratingCountPosition === 'right' && (
|
||||||
<AppInfoUserName>
|
<AppInfoUserName>
|
||||||
{(votesInfo?.totalVotes ?? 0) +
|
{(votesInfo?.totalVotes ?? 0) +
|
||||||
(votesInfo?.voteCounts?.length === 6 ? 1 : 0)}
|
(votesInfo?.voteCounts?.length === 6 ? 1 : 0)}
|
||||||
|
@ -4,8 +4,8 @@ import {
|
|||||||
AppsNavBarParent,
|
AppsNavBarParent,
|
||||||
AppsNavBarRight,
|
AppsNavBarRight,
|
||||||
} from './Apps-styles';
|
} from './Apps-styles';
|
||||||
import { NavBack } from '../../assets/svgs/NavBack.tsx';
|
import { NavBack } from '../../assets/Icons/NavBack.tsx';
|
||||||
import { NavAdd } from '../../assets/svgs/NavAdd.tsx';
|
import { NavAdd } from '../../assets/Icons/NavAdd.tsx';
|
||||||
import { ButtonBase, Tab, Tabs } from '@mui/material';
|
import { ButtonBase, Tab, Tabs } from '@mui/material';
|
||||||
import {
|
import {
|
||||||
executeEvent,
|
executeEvent,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TabParent } from './Apps-styles';
|
import { TabParent } from './Apps-styles';
|
||||||
import { NavCloseTab } from '../../assets/svgs/NavCloseTab.tsx';
|
import { NavCloseTab } from '../../assets/Icons/NavCloseTab.tsx';
|
||||||
import { getBaseApiReact } from '../../App';
|
import { getBaseApiReact } from '../../App';
|
||||||
import { Avatar, ButtonBase } from '@mui/material';
|
import { Avatar, ButtonBase } from '@mui/material';
|
||||||
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
||||||
|
@ -4,9 +4,9 @@ import {
|
|||||||
AppsNavBarParent,
|
AppsNavBarParent,
|
||||||
AppsNavBarRight,
|
AppsNavBarRight,
|
||||||
} from './Apps-styles';
|
} from './Apps-styles';
|
||||||
import { NavBack } from '../../assets/svgs/NavBack.tsx';
|
import { NavBack } from '../../assets/Icons/NavBack.tsx';
|
||||||
import { NavAdd } from '../../assets/svgs/NavAdd.tsx';
|
import { NavAdd } from '../../assets/Icons/NavAdd.tsx';
|
||||||
import { NavMoreMenu } from '../../assets/svgs/NavMoreMenu.tsx';
|
import { NavMoreMenu } from '../../assets/Icons/NavMoreMenu.tsx';
|
||||||
import {
|
import {
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
|
@ -4,9 +4,9 @@ import {
|
|||||||
AppsNavBarParent,
|
AppsNavBarParent,
|
||||||
AppsNavBarRight,
|
AppsNavBarRight,
|
||||||
} from './Apps-styles';
|
} from './Apps-styles';
|
||||||
import { NavBack } from '../../assets/svgs/NavBack.tsx';
|
import { NavBack } from '../../assets/Icons/NavBack.tsx';
|
||||||
import { NavAdd } from '../../assets/svgs/NavAdd.tsx';
|
import { NavAdd } from '../../assets/Icons/NavAdd.tsx';
|
||||||
import { NavMoreMenu } from '../../assets/svgs/NavMoreMenu.tsx';
|
import { NavMoreMenu } from '../../assets/Icons/NavMoreMenu.tsx';
|
||||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
import {
|
import {
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TabParent } from './Apps-styles';
|
import { TabParent } from './Apps-styles';
|
||||||
import { NavCloseTab } from '../../assets/svgs/NavCloseTab.tsx';
|
import { NavCloseTab } from '../../assets/Icons/NavCloseTab.tsx';
|
||||||
import { getBaseApiReact } from '../../App';
|
import { getBaseApiReact } from '../../App';
|
||||||
import { Avatar, ButtonBase, useTheme } from '@mui/material';
|
import { Avatar, ButtonBase, useTheme } from '@mui/material';
|
||||||
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
||||||
|
@ -33,8 +33,8 @@ import {
|
|||||||
import { ReusableModal } from './ReusableModal';
|
import { ReusableModal } from './ReusableModal';
|
||||||
import { Spacer } from '../../../common/Spacer';
|
import { Spacer } from '../../../common/Spacer';
|
||||||
import { formatBytes } from '../../../utils/Size';
|
import { formatBytes } from '../../../utils/Size';
|
||||||
import { CreateThreadIcon } from '../../../assets/svgs/CreateThreadIcon';
|
import { CreateThreadIcon } from '../../../assets/Icons/CreateThreadIcon';
|
||||||
import { SendNewMessage } from '../../../assets/svgs/SendNewMessage';
|
import { SendNewMessage } from '../../../assets/Icons/SendNewMessage';
|
||||||
import { TextEditor } from './TextEditor';
|
import { TextEditor } from './TextEditor';
|
||||||
import {
|
import {
|
||||||
MyContext,
|
MyContext,
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import { navigationControllerAtom } from '../../atoms/global';
|
import { navigationControllerAtom } from '../../atoms/global';
|
||||||
import { AppsNavBarLeft, AppsNavBarParent } from '../Apps/Apps-styles';
|
import { AppsNavBarLeft, AppsNavBarParent } from '../Apps/Apps-styles';
|
||||||
import { NavBack } from '../../assets/svgs/NavBack.tsx';
|
import { NavBack } from '../../assets/Icons/NavBack.tsx';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
|
|
||||||
export const WalletsAppWrapper = () => {
|
export const WalletsAppWrapper = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useContext, useEffect, useMemo, useState } from "react";
|
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import isEqual from "lodash/isEqual"; // Import deep comparison utility
|
import isEqual from 'lodash/isEqual'; // Import deep comparison utility
|
||||||
import {
|
import {
|
||||||
canSaveSettingToQdnAtom,
|
canSaveSettingToQdnAtom,
|
||||||
hasSettingsChangedAtom,
|
hasSettingsChangedAtom,
|
||||||
@ -9,35 +9,35 @@ import {
|
|||||||
settingsLocalLastUpdatedAtom,
|
settingsLocalLastUpdatedAtom,
|
||||||
settingsQDNLastUpdatedAtom,
|
settingsQDNLastUpdatedAtom,
|
||||||
sortablePinnedAppsAtom,
|
sortablePinnedAppsAtom,
|
||||||
} from "../../atoms/global";
|
} from '../../atoms/global';
|
||||||
import { Box, Button, ButtonBase, Popover, Typography } from "@mui/material";
|
import { Box, Button, ButtonBase, Popover, Typography } from '@mui/material';
|
||||||
import { objectToBase64 } from "../../qdn/encryption/group-encryption";
|
import { objectToBase64 } from '../../qdn/encryption/group-encryption';
|
||||||
import { MyContext } from "../../App";
|
import { MyContext } from '../../App';
|
||||||
import { getFee } from "../../background";
|
import { getFee } from '../../background';
|
||||||
import { CustomizedSnackbars } from "../Snackbar/Snackbar";
|
import { CustomizedSnackbars } from '../Snackbar/Snackbar';
|
||||||
import { SaveIcon } from "../../assets/svgs/SaveIcon";
|
import { SaveIcon } from '../../assets/Icons/SaveIcon';
|
||||||
import { IconWrapper } from "../Desktop/DesktopFooter";
|
import { IconWrapper } from '../Desktop/DesktopFooter';
|
||||||
import { Spacer } from "../../common/Spacer";
|
import { Spacer } from '../../common/Spacer';
|
||||||
import { LoadingButton } from "@mui/lab";
|
import { LoadingButton } from '@mui/lab';
|
||||||
import { saveToLocalStorage } from "../Apps/AppsNavBar";
|
import { saveToLocalStorage } from '../Apps/AppsNavBar';
|
||||||
import { decryptData, encryptData } from "../../qortalRequests/get";
|
import { decryptData, encryptData } from '../../qortalRequests/get';
|
||||||
import { saveFileToDiskGeneric } from "../../utils/generateWallet/generateWallet";
|
import { saveFileToDiskGeneric } from '../../utils/generateWallet/generateWallet';
|
||||||
import {
|
import {
|
||||||
base64ToUint8Array,
|
base64ToUint8Array,
|
||||||
uint8ArrayToObject,
|
uint8ArrayToObject,
|
||||||
} from "../../backgroundFunctions/encryption";
|
} from '../../backgroundFunctions/encryption';
|
||||||
|
|
||||||
export const handleImportClick = async () => {
|
export const handleImportClick = async () => {
|
||||||
const fileInput = document.createElement("input");
|
const fileInput = document.createElement('input');
|
||||||
fileInput.type = "file";
|
fileInput.type = 'file';
|
||||||
fileInput.accept = ".base64,.txt";
|
fileInput.accept = '.base64,.txt';
|
||||||
|
|
||||||
// Create a promise to handle file selection and reading synchronously
|
// Create a promise to handle file selection and reading synchronously
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
fileInput.onchange = () => {
|
fileInput.onchange = () => {
|
||||||
const file = fileInput.files[0];
|
const file = fileInput.files[0];
|
||||||
if (!file) {
|
if (!file) {
|
||||||
reject(new Error("No file selected"));
|
reject(new Error('No file selected'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ export const handleImportClick = async () => {
|
|||||||
resolve(e.target.result); // Resolve with the file content
|
resolve(e.target.result); // Resolve with the file content
|
||||||
};
|
};
|
||||||
reader.onerror = () => {
|
reader.onerror = () => {
|
||||||
reject(new Error("Error reading file"));
|
reject(new Error('Error reading file'));
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.readAsText(file); // Read the file as text (Base64 string)
|
reader.readAsText(file); // Read the file as text (Base64 string)
|
||||||
@ -124,7 +124,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
const encryptData = await new Promise((res, rej) => {
|
const encryptData = await new Promise((res, rej) => {
|
||||||
window
|
window
|
||||||
.sendMessage(
|
.sendMessage(
|
||||||
"ENCRYPT_DATA",
|
'ENCRYPT_DATA',
|
||||||
{
|
{
|
||||||
data64,
|
data64,
|
||||||
},
|
},
|
||||||
@ -139,23 +139,23 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("Failed qortalRequest", error);
|
console.error('Failed qortalRequest', error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (encryptData && !encryptData?.error) {
|
if (encryptData && !encryptData?.error) {
|
||||||
const fee = await getFee("ARBITRARY");
|
const fee = await getFee('ARBITRARY');
|
||||||
|
|
||||||
await show({
|
await show({
|
||||||
message:
|
message:
|
||||||
"Would you like to publish your settings to QDN (encrypted) ?",
|
'Would you like to publish your settings to QDN (encrypted) ?',
|
||||||
publishFee: fee.fee + " QORT",
|
publishFee: fee.fee + ' QORT',
|
||||||
});
|
});
|
||||||
const response = await new Promise((res, rej) => {
|
const response = await new Promise((res, rej) => {
|
||||||
window
|
window
|
||||||
.sendMessage("publishOnQDN", {
|
.sendMessage('publishOnQDN', {
|
||||||
data: encryptData,
|
data: encryptData,
|
||||||
identifier: "ext_saved_settings",
|
identifier: 'ext_saved_settings',
|
||||||
service: "DOCUMENT_PRIVATE",
|
service: 'DOCUMENT_PRIVATE',
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (!response?.error) {
|
if (!response?.error) {
|
||||||
@ -165,15 +165,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
rej(response.error);
|
rej(response.error);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
rej(error.message || "An error occurred");
|
rej(error.message || 'An error occurred');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (response?.identifier) {
|
if (response?.identifier) {
|
||||||
setOldPinnedApps(pinnedApps);
|
setOldPinnedApps(pinnedApps);
|
||||||
setSettingsQdnLastUpdated(Date.now());
|
setSettingsQdnLastUpdated(Date.now());
|
||||||
setInfoSnack({
|
setInfoSnack({
|
||||||
type: "success",
|
type: 'success',
|
||||||
message: "Sucessfully published to QDN",
|
message: 'Sucessfully published to QDN',
|
||||||
});
|
});
|
||||||
setOpenSnack(true);
|
setOpenSnack(true);
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
@ -181,8 +181,8 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setInfoSnack({
|
setInfoSnack({
|
||||||
type: "error",
|
type: 'error',
|
||||||
message: error?.message || "Unable to save to QDN",
|
message: error?.message || 'Unable to save to QDN',
|
||||||
});
|
});
|
||||||
setOpenSnack(true);
|
setOpenSnack(true);
|
||||||
} finally {
|
} finally {
|
||||||
@ -196,7 +196,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
|
|
||||||
const revertChanges = () => {
|
const revertChanges = () => {
|
||||||
setPinnedApps(oldPinnedApps);
|
setPinnedApps(oldPinnedApps);
|
||||||
saveToLocalStorage("ext_saved_settings", "sortablePinnedApps", null);
|
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', null);
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -218,11 +218,11 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
selected={false}
|
selected={false}
|
||||||
>
|
>
|
||||||
<SaveIcon
|
<SaveIcon
|
||||||
color={hasChanged && !isLoading ? "#5EB049" : undefined}
|
color={hasChanged && !isLoading ? '#5EB049' : undefined}
|
||||||
/>
|
/>
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
) : (
|
) : (
|
||||||
<SaveIcon color={hasChanged && !isLoading ? "#5EB049" : undefined} />
|
<SaveIcon color={hasChanged && !isLoading ? '#5EB049' : undefined} />
|
||||||
)}
|
)}
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<Popover
|
<Popover
|
||||||
@ -230,41 +230,41 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
onClose={() => setAnchorEl(null)} // Close popover on click outside
|
onClose={() => setAnchorEl(null)} // Close popover on click outside
|
||||||
anchorOrigin={{
|
anchorOrigin={{
|
||||||
vertical: "bottom",
|
vertical: 'bottom',
|
||||||
horizontal: "center",
|
horizontal: 'center',
|
||||||
}}
|
}}
|
||||||
transformOrigin={{
|
transformOrigin={{
|
||||||
vertical: "top",
|
vertical: 'top',
|
||||||
horizontal: "center",
|
horizontal: 'center',
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
width: "300px",
|
width: '300px',
|
||||||
maxWidth: "90%",
|
maxWidth: '90%',
|
||||||
maxHeight: "80%",
|
maxHeight: '80%',
|
||||||
overflow: "auto",
|
overflow: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isUsingImportExportSettings && (
|
{isUsingImportExportSettings && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
padding: "15px",
|
padding: '15px',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
gap: 1,
|
gap: 1,
|
||||||
width: "100%",
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
You are using the export/import way of saving settings.
|
You are using the export/import way of saving settings.
|
||||||
@ -274,8 +274,8 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
saveToLocalStorage(
|
saveToLocalStorage(
|
||||||
"ext_saved_settings_import_export",
|
'ext_saved_settings_import_export',
|
||||||
"sortablePinnedApps",
|
'sortablePinnedApps',
|
||||||
null,
|
null,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -283,13 +283,13 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
}}
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
fontWeight: "bold",
|
fontWeight: 'bold',
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
"&:hover": {
|
'&:hover': {
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -302,25 +302,25 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
{!isUsingImportExportSettings && (
|
{!isUsingImportExportSettings && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
padding: "15px",
|
padding: '15px',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
gap: 1,
|
gap: 1,
|
||||||
width: "100%",
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{!myName ? (
|
{!myName ? (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
You need a registered Qortal name to save your pinned apps to
|
You need a registered Qortal name to save your pinned apps to
|
||||||
@ -332,15 +332,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
{hasChanged && (
|
{hasChanged && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
You have unsaved changes to your pinned apps. Save them to
|
You have unsaved changes to your pinned apps. Save them to
|
||||||
@ -349,13 +349,13 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
<Spacer height="10px" />
|
<Spacer height="10px" />
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "var(--green)",
|
backgroundColor: 'var(--green)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
fontWeight: "bold",
|
fontWeight: 'bold',
|
||||||
"&:hover": {
|
'&:hover': {
|
||||||
backgroundColor: "var(--green)",
|
backgroundColor: 'var(--green)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -372,7 +372,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
<>
|
<>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Don't like your current local changes? Would you
|
Don't like your current local changes? Would you
|
||||||
@ -385,13 +385,13 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
onClick={revertChanges}
|
onClick={revertChanges}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
fontWeight: "bold",
|
fontWeight: 'bold',
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
"&:hover": {
|
'&:hover': {
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -405,7 +405,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
<>
|
<>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Don't like your current local changes? Would you
|
Don't like your current local changes? Would you
|
||||||
@ -428,15 +428,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
isUsingImportExportSettings !== true && (
|
isUsingImportExportSettings !== true && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
The app was unable to download your existing QDN-saved
|
The app was unable to download your existing QDN-saved
|
||||||
@ -449,13 +449,13 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
onClick={saveToQdn}
|
onClick={saveToQdn}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
fontWeight: "bold",
|
fontWeight: 'bold',
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
"&:hover": {
|
'&:hover': {
|
||||||
backgroundColor: "var(--danger)",
|
backgroundColor: 'var(--danger)',
|
||||||
color: "black",
|
color: 'black',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -467,15 +467,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
{!hasChanged && (
|
{!hasChanged && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "14px",
|
fontSize: '14px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
You currently do not have any changes to your pinned apps
|
You currently do not have any changes to your pinned apps
|
||||||
@ -488,19 +488,19 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
)}
|
)}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
padding: "15px",
|
padding: '15px',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
gap: 1,
|
gap: 1,
|
||||||
width: "100%",
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
gap: "10px",
|
gap: '10px',
|
||||||
justifyContent: "flex-end",
|
justifyContent: 'flex-end',
|
||||||
width: "100%",
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
@ -517,8 +517,8 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
);
|
);
|
||||||
if (Array.isArray(responseData)) {
|
if (Array.isArray(responseData)) {
|
||||||
saveToLocalStorage(
|
saveToLocalStorage(
|
||||||
"ext_saved_settings_import_export",
|
'ext_saved_settings_import_export',
|
||||||
"sortablePinnedApps",
|
'sortablePinnedApps',
|
||||||
responseData,
|
responseData,
|
||||||
{
|
{
|
||||||
isUsingImportExport: true,
|
isUsingImportExport: true,
|
||||||
@ -529,7 +529,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
setIsUsingImportExportSettings(true);
|
setIsUsingImportExportSettings(true);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
console.log('error', error);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -544,14 +544,14 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
|||||||
data64,
|
data64,
|
||||||
});
|
});
|
||||||
const blob = new Blob([encryptedData], {
|
const blob = new Blob([encryptedData], {
|
||||||
type: "text/plain",
|
type: 'text/plain',
|
||||||
});
|
});
|
||||||
|
|
||||||
const timestamp = new Date().toISOString().replace(/:/g, "-"); // Safe timestamp for filenames
|
const timestamp = new Date().toISOString().replace(/:/g, '-'); // Safe timestamp for filenames
|
||||||
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
|
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
|
||||||
await saveFileToDiskGeneric(blob, filename);
|
await saveFileToDiskGeneric(blob, filename);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
console.log('error', error);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user