Move tsx into proper folder

This commit is contained in:
Nicola Benaglia 2025-04-20 09:44:43 +02:00
parent 6dea8e2468
commit d0cfc4db2f
25 changed files with 229 additions and 234 deletions

View File

@ -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';

View File

@ -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,

View File

@ -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

View File

@ -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)}

View File

@ -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,

View File

@ -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';

View File

@ -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,

View File

@ -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,

View File

@ -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';

View File

@ -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,

View File

@ -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 = () => {

View File

@ -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);
} }
}} }}
> >