mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-07-23 04:36:52 +00:00
Merge pull request #15 from nbenaglia/feature/css-light-and-switch
Add themeSelector and switcher (dark and light styles)
This commit is contained in:
@@ -20,7 +20,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode,
|
||||
padding: 0;
|
||||
}
|
||||
* {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
-msOverflowStyle: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
|
@@ -1,315 +1,381 @@
|
||||
import {
|
||||
AppBar,
|
||||
Button,
|
||||
Toolbar,
|
||||
Typography,
|
||||
Box,
|
||||
TextField,
|
||||
InputLabel,
|
||||
ButtonBase,
|
||||
} from "@mui/material";
|
||||
import { styled } from "@mui/system";
|
||||
|
||||
export const AppsParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
alignItems: "center",
|
||||
overflow: 'auto',
|
||||
// For WebKit-based browsers (Chrome, Safari, etc.)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px", // Set the width to 0 to hide the scrollbar
|
||||
height: "0px", // Set the height to 0 for horizontal scrollbar
|
||||
},
|
||||
|
||||
// For Firefox
|
||||
scrollbarWidth: "none", // Hides the scrollbar in Firefox
|
||||
|
||||
// Optional for better cross-browser consistency
|
||||
"-ms-overflow-style": "none" // Hides scrollbar in IE and Edge
|
||||
}));
|
||||
export const AppsContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: 'space-evenly',
|
||||
gap: '24px',
|
||||
flexWrap: 'wrap',
|
||||
alignItems: 'flex-start',
|
||||
alignSelf: 'center'
|
||||
|
||||
}));
|
||||
export const AppsLibraryContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
export const AppsWidthLimiter = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'flex-start',
|
||||
}));
|
||||
export const AppsSearchContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#434343',
|
||||
borderRadius: '8px',
|
||||
padding: '0px 10px',
|
||||
height: '36px'
|
||||
}));
|
||||
export const AppsSearchLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
flexGrow: 1,
|
||||
flexShrink: 0
|
||||
}));
|
||||
export const AppsSearchRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
flexShrink: 1
|
||||
}));
|
||||
export const AppCircleContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: '5px',
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
}));
|
||||
export const Add = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '36px',
|
||||
fontWeight: 500,
|
||||
lineHeight: '43.57px',
|
||||
textAlign: 'left'
|
||||
|
||||
}));
|
||||
export const AppCircleLabel = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '14px',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
// whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
width: '120%',
|
||||
'-webkit-line-clamp': '2',
|
||||
'-webkit-box-orient': 'vertical',
|
||||
'display': '-webkit-box',
|
||||
|
||||
}));
|
||||
export const AppLibrarySubTitle = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '16px',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
}));
|
||||
export const AppCircle = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "75px",
|
||||
flexDirection: "column",
|
||||
height: "75px",
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: "var(--apps-circle)",
|
||||
border: '1px solid #FFFFFF'
|
||||
}));
|
||||
import { Typography, Box, ButtonBase } from "@mui/material";
|
||||
import { styled } from "@mui/system";
|
||||
|
||||
export const AppInfoSnippetContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
}));
|
||||
export const AppsParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
alignItems: "center",
|
||||
overflow: "auto",
|
||||
// For WebKit-based browsers (Chrome, Safari, etc.)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px", // Set the width to 0 to hide the scrollbar
|
||||
height: "0px", // Set the height to 0 for horizontal scrollbar
|
||||
},
|
||||
|
||||
export const AppInfoSnippetLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
gap: '12px'
|
||||
}));
|
||||
export const AppInfoSnippetRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
// For Firefox
|
||||
scrollbarWidth: "none", // Hides the scrollbar in Firefox
|
||||
|
||||
export const AppDownloadButton = styled(ButtonBase)(({ theme }) => ({
|
||||
backgroundColor: "#247C0E",
|
||||
width: '101px',
|
||||
height: '29px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: '25px',
|
||||
alignSelf: 'center'
|
||||
}));
|
||||
// Optional for better cross-browser consistency
|
||||
"-msOverflowStyle": "none", // Hides scrollbar in IE and Edge
|
||||
|
||||
export const AppDownloadButtonText = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '14px',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
}));
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppPublishTagsContainer = styled(Box)(({theme})=> ({
|
||||
gap: '10px',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'flex-start',
|
||||
width: '100%',
|
||||
display: 'flex'
|
||||
}))
|
||||
export const AppsContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: "space-evenly",
|
||||
gap: "24px",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "flex-start",
|
||||
alignSelf: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsLibraryContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
}));
|
||||
|
||||
export const AppInfoSnippetMiddle = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-start',
|
||||
}));
|
||||
export const AppsWidthLimiter = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
flexDirection: "column",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "flex-start",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppInfoAppName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '16px',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
textAlign: 'start'
|
||||
}));
|
||||
export const AppInfoUserName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '13px',
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.2,
|
||||
color: '#8D8F93',
|
||||
textAlign: 'start'
|
||||
}));
|
||||
export const AppsSearchContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
borderRadius: "8px",
|
||||
padding: "0px 10px",
|
||||
height: "36px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsSearchLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
flexGrow: 1,
|
||||
flexShrink: 0,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsNavBarParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: '60px',
|
||||
backgroundColor: '#1F2023',
|
||||
padding: '0px 10px',
|
||||
position: "fixed",
|
||||
bottom: 0,
|
||||
zIndex: 1,
|
||||
}));
|
||||
export const AppsSearchRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "90%",
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "center",
|
||||
flexShrink: 1,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsNavBarLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
flexGrow: 1
|
||||
}));
|
||||
export const AppsNavBarRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
export const AppCircleContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "5px",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const TabParent = styled(Box)(({ theme }) => ({
|
||||
height: '36px',
|
||||
width: '36px',
|
||||
backgroundColor: '#434343',
|
||||
position: 'relative',
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}));
|
||||
export const Add = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "36px",
|
||||
fontWeight: 500,
|
||||
lineHeight: "43.57px",
|
||||
textAlign: "left",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTAParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
backgroundColor: '#181C23'
|
||||
}));
|
||||
export const AppCircleLabel = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "14px",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
// whiteSpace: 'nowrap',
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
width: "120%",
|
||||
"-webkit-line-clamp": "2",
|
||||
"-webkit-box-orient": "vertical",
|
||||
display: "-webkit-box",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTALeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
export const PublishQAppCTARight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
export const AppLibrarySubTitle = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTAButton = styled(ButtonBase)(({ theme }) => ({
|
||||
width: '101px',
|
||||
height: '29px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: '25px',
|
||||
border: '1px solid #FFFFFF'
|
||||
}));
|
||||
export const PublishQAppDotsBG = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
backgroundColor: '#4BBCFE'
|
||||
}));
|
||||
|
||||
export const PublishQAppInfo = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '10px',
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.2,
|
||||
fontStyle: 'italic'
|
||||
}));
|
||||
export const AppCircle = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "75px",
|
||||
flexDirection: "column",
|
||||
height: "75px",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
border: "1px solid #FFFFFF",
|
||||
}));
|
||||
|
||||
export const PublishQAppChoseFile = styled(ButtonBase)(({ theme }) => ({
|
||||
width: '101px',
|
||||
height: '30px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: '5px',
|
||||
backgroundColor: '#0091E1',
|
||||
color: 'white',
|
||||
fontWeight: 600,
|
||||
fontSize: '10px'
|
||||
}));
|
||||
export const AppInfoSnippetContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppInfoSnippetLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
gap: "12px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfo = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
}));
|
||||
export const AppInfoSnippetRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfoSub = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: 'column',
|
||||
}));
|
||||
export const AppsCategoryInfoLabel = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '12px',
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.2,
|
||||
color: '#8D8F93',
|
||||
}));
|
||||
export const AppsCategoryInfoValue = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
color: '#8D8F93',
|
||||
}));
|
||||
export const AppsInfoDescription = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '13px',
|
||||
fontWeight: 300,
|
||||
lineHeight: 1.2,
|
||||
width: '90%',
|
||||
textAlign: 'start'
|
||||
}));
|
||||
export const AppDownloadButton = styled(ButtonBase)(({ theme }) => ({
|
||||
backgroundColor: "#247C0E",
|
||||
color: theme.palette.text.primary,
|
||||
width: "101px",
|
||||
height: "29px",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
borderRadius: "25px",
|
||||
alignSelf: "center",
|
||||
}));
|
||||
|
||||
export const AppDownloadButtonText = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "14px",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppPublishTagsContainer = styled(Box)(({ theme }) => ({
|
||||
gap: "10px",
|
||||
flexWrap: "wrap",
|
||||
justifyContent: "flex-start",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppInfoSnippetMiddle = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "flex-start",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppInfoAppName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "16px",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
textAlign: "start",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppInfoUserName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "13px",
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.2,
|
||||
textAlign: "start",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsNavBarParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
height: "60px",
|
||||
padding: "0px 10px",
|
||||
position: "fixed",
|
||||
bottom: 0,
|
||||
zIndex: 1,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsNavBarLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
flexGrow: 1,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsNavBarRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const TabParent = styled(Box)(({ theme }) => ({
|
||||
height: "36px",
|
||||
width: "36px",
|
||||
position: "relative",
|
||||
borderRadius: "50%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTAParent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTALeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTARight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "center",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppCTAButton = styled(ButtonBase)(({ theme }) => ({
|
||||
width: "101px",
|
||||
height: "29px",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
borderRadius: "25px",
|
||||
border: "1px solid #FFFFFF",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppDotsBG = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: "60px",
|
||||
height: "60px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppInfo = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "10px",
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.2,
|
||||
fontStyle: "italic",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const PublishQAppChoseFile = styled(ButtonBase)(({ theme }) => ({
|
||||
width: "101px",
|
||||
height: "30px",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
borderRadius: "5px",
|
||||
fontWeight: 600,
|
||||
fontSize: "10px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfo = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfoSub = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfoLabel = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "12px",
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.2,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsCategoryInfoValue = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "12px",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const AppsInfoDescription = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "13px",
|
||||
fontWeight: 300,
|
||||
lineHeight: 1.2,
|
||||
width: "90%",
|
||||
textAlign: "start",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
@@ -56,7 +56,7 @@ const ScrollerStyled = styled('div')({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled('div')({
|
||||
@@ -75,7 +75,7 @@ const ScrollerStyled = styled('div')({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
export const AppsCategory = ({ availableQapps, myName, category, isShow }) => {
|
||||
|
@@ -64,7 +64,7 @@ const ScrollerStyled = styled("div")({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled("div")({
|
||||
@@ -83,7 +83,7 @@ const StyledVirtuosoContainer = styled("div")({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
export const AppsCategoryDesktop = ({
|
||||
|
@@ -1,7 +1,13 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import React, {
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { AppsHomeDesktop } from "./AppsHomeDesktop";
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { GlobalContext, MyContext, getBaseApiReact } from "../../App";
|
||||
import { GlobalContext, getBaseApiReact } from "../../App";
|
||||
import { AppInfo } from "./AppInfo";
|
||||
import {
|
||||
executeEvent,
|
||||
@@ -15,47 +21,58 @@ import { AppPublish } from "./AppPublish";
|
||||
import { AppsLibraryDesktop } from "./AppsLibraryDesktop";
|
||||
import { AppsCategoryDesktop } from "./AppsCategoryDesktop";
|
||||
import { AppsNavBarDesktop } from "./AppsNavBarDesktop";
|
||||
import { Box, ButtonBase } from "@mui/material";
|
||||
import { Box, ButtonBase, useTheme } from "@mui/material";
|
||||
import { HomeIcon } from "../../assets/Icons/HomeIcon";
|
||||
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||
import { Save } from "../Save/Save";
|
||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||
import { CoreSyncStatus } from "../CoreSyncStatus";
|
||||
import { IconWrapper } from "../Desktop/DesktopFooter";
|
||||
import AppIcon from "../../assets/svgs/AppIcon.svg";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { enabledDevModeAtom } from "../../atoms/global";
|
||||
import { AppsIcon } from "../../assets/Icons/AppsIcon";
|
||||
|
||||
const uid = new ShortUniqueId({ length: 8 });
|
||||
|
||||
export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktopSideView, hasUnreadDirects, isDirects, isGroups, hasUnreadGroups, toggleSideViewGroups, toggleSideViewDirects, setDesktopViewMode, isApps, desktopViewMode}) => {
|
||||
export const AppsDesktop = ({
|
||||
mode,
|
||||
setMode,
|
||||
show,
|
||||
myName,
|
||||
goToHome,
|
||||
hasUnreadDirects,
|
||||
hasUnreadGroups,
|
||||
setDesktopViewMode,
|
||||
desktopViewMode,
|
||||
}) => {
|
||||
const [availableQapps, setAvailableQapps] = useState([]);
|
||||
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
|
||||
const [selectedCategory, setSelectedCategory] = useState(null)
|
||||
const [selectedCategory, setSelectedCategory] = useState(null);
|
||||
const [tabs, setTabs] = useState([]);
|
||||
const [selectedTab, setSelectedTab] = useState(null);
|
||||
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
|
||||
const [categories, setCategories] = useState([])
|
||||
const [categories, setCategories] = useState([]);
|
||||
const iframeRefs = useRef({});
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] =
|
||||
useRecoilState(enabledDevModeAtom);
|
||||
const { showTutorial } = useContext(GlobalContext);
|
||||
const theme = useTheme();
|
||||
|
||||
const myApp = useMemo(()=> {
|
||||
|
||||
return availableQapps.find((app)=> app.name === myName && app.service === 'APP')
|
||||
}, [myName, availableQapps])
|
||||
const myWebsite = useMemo(()=> {
|
||||
|
||||
return availableQapps.find((app)=> app.name === myName && app.service === 'WEBSITE')
|
||||
}, [myName, availableQapps])
|
||||
const myApp = useMemo(() => {
|
||||
return availableQapps.find(
|
||||
(app) => app.name === myName && app.service === "APP"
|
||||
);
|
||||
}, [myName, availableQapps]);
|
||||
|
||||
const myWebsite = useMemo(() => {
|
||||
return availableQapps.find(
|
||||
(app) => app.name === myName && app.service === "WEBSITE"
|
||||
);
|
||||
}, [myName, availableQapps]);
|
||||
|
||||
useEffect(()=> {
|
||||
if(show){
|
||||
showTutorial('qapps')
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
showTutorial("qapps");
|
||||
}
|
||||
}, [show])
|
||||
}, [show]);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
@@ -81,10 +98,10 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
});
|
||||
if (!response?.ok) return;
|
||||
const responseData = await response.json();
|
||||
|
||||
|
||||
setCategories(responseData);
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
// dispatch(setIsLoadingGlobal(false))
|
||||
}
|
||||
@@ -115,18 +132,19 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
});
|
||||
if (!responseWebsites?.ok) return;
|
||||
const responseDataWebsites = await responseWebsites.json();
|
||||
|
||||
|
||||
apps = responseData;
|
||||
websites = responseDataWebsites;
|
||||
const combine = [...apps, ...websites];
|
||||
setAvailableQapps(combine);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
// dispatch(setIsLoadingGlobal(false))
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
getCategories()
|
||||
getCategories();
|
||||
}, [getCategories]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -163,12 +181,13 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
subscribeToEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc);
|
||||
|
||||
return () => {
|
||||
unsubscribeFromEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc);
|
||||
unsubscribeFromEvent(
|
||||
"selectedAppInfoCategory",
|
||||
selectedAppInfoCategoryFunc
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
const selectedCategoryFunc = (e) => {
|
||||
const data = e.detail?.data;
|
||||
setSelectedCategory(data);
|
||||
@@ -183,35 +202,37 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const navigateBackFunc = (e) => {
|
||||
if (['category', 'appInfo-from-category', 'appInfo', 'library', 'publish'].includes(mode)) {
|
||||
if (
|
||||
[
|
||||
"category",
|
||||
"appInfo-from-category",
|
||||
"appInfo",
|
||||
"library",
|
||||
"publish",
|
||||
].includes(mode)
|
||||
) {
|
||||
// Handle the various modes as needed
|
||||
if (mode === 'category') {
|
||||
setMode('library');
|
||||
if (mode === "category") {
|
||||
setMode("library");
|
||||
setSelectedCategory(null);
|
||||
} else if (mode === 'appInfo-from-category') {
|
||||
setMode('category');
|
||||
} else if (mode === 'appInfo') {
|
||||
setMode('library');
|
||||
} else if (mode === 'library') {
|
||||
} else if (mode === "appInfo-from-category") {
|
||||
setMode("category");
|
||||
} else if (mode === "appInfo") {
|
||||
setMode("library");
|
||||
} else if (mode === "library") {
|
||||
if (isNewTabWindow) {
|
||||
setMode('viewer');
|
||||
setMode("viewer");
|
||||
} else {
|
||||
setMode('home');
|
||||
setMode("home");
|
||||
}
|
||||
} else if (mode === 'publish') {
|
||||
setMode('library');
|
||||
} else if (mode === "publish") {
|
||||
setMode("library");
|
||||
}
|
||||
} else if(selectedTab?.tabId) {
|
||||
executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {})
|
||||
} else if (selectedTab?.tabId) {
|
||||
executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
subscribeToEvent("navigateBack", navigateBackFunc);
|
||||
@@ -234,8 +255,6 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
setIsNewTabWindow(false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
subscribeToEvent("addTab", addTabFunc);
|
||||
|
||||
@@ -245,7 +264,7 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
}, [tabs]);
|
||||
const setSelectedTabFunc = (e) => {
|
||||
const data = e.detail?.data;
|
||||
if(e.detail?.isDevMode) return
|
||||
if (e.detail?.isDevMode) return;
|
||||
|
||||
setSelectedTab(data);
|
||||
setTimeout(() => {
|
||||
@@ -259,7 +278,6 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
}, 100);
|
||||
setIsNewTabWindow(false);
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
subscribeToEvent("setSelectedTab", setSelectedTabFunc);
|
||||
@@ -299,7 +317,7 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
|
||||
const setNewTabWindowFunc = (e) => {
|
||||
setIsNewTabWindow(true);
|
||||
setSelectedTab(null)
|
||||
setSelectedTab(null);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -318,67 +336,62 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
flexDirection: 'row'
|
||||
}}
|
||||
>
|
||||
|
||||
<Box sx={{
|
||||
width: '60px',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
gap: '25px'
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
width: "60px",
|
||||
flexDirection: "column",
|
||||
height: "100vh",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
gap: "25px",
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
paddingTop: '23px'
|
||||
width: "60px",
|
||||
height: "60px",
|
||||
paddingTop: "23px",
|
||||
}}
|
||||
onClick={() => {
|
||||
goToHome();
|
||||
|
||||
}}
|
||||
>
|
||||
|
||||
<HomeIcon
|
||||
height={34}
|
||||
color={desktopViewMode === 'home' ? 'white': "rgba(250, 250, 250, 0.5)"}
|
||||
/>
|
||||
|
||||
<HomeIcon height={34} />
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('apps')
|
||||
setDesktopViewMode("apps");
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Apps" disableWidth>
|
||||
<AppsIcon height={30} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("chat");
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={isApps ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||
label="Apps"
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon height={30} color={isApps ? 'white' :"rgba(250, 250, 250, 0.5)"} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('chat')
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={(hasUnreadDirects || hasUnreadGroups) ? "var(--unread)" : desktopViewMode === 'chat' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||
color={
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--unread)"
|
||||
: theme.palette.text.primary
|
||||
}
|
||||
label="Chat"
|
||||
disableWidth
|
||||
>
|
||||
<MessagingIcon
|
||||
height={30}
|
||||
color={
|
||||
(hasUnreadDirects || hasUnreadGroups)
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--unread)"
|
||||
: desktopViewMode === 'chat'
|
||||
? "white"
|
||||
: "rgba(250, 250, 250, 0.5)"
|
||||
: theme.palette.text.primary
|
||||
}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
{/* <ButtonBase
|
||||
onClick={() => {
|
||||
@@ -417,65 +430,78 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
/>
|
||||
|
||||
</ButtonBase> */}
|
||||
<Save isDesktop disableWidth myName={myName}/>
|
||||
<Save isDesktop disableWidth myName={myName} />
|
||||
{isEnabledDevMode && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('dev')
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"}
|
||||
label="Dev"
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("dev");
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Dev" disableWidth>
|
||||
<AppsIcon height={30} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
)}
|
||||
{mode !== 'home' && (
|
||||
<AppsNavBarDesktop disableBack={isNewTabWindow && mode === 'viewer'} />
|
||||
|
||||
{mode !== "home" && (
|
||||
<AppsNavBarDesktop
|
||||
disableBack={isNewTabWindow && mode === "viewer"}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
|
||||
|
||||
{mode === "home" && (
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
overflow: 'auto'
|
||||
}}>
|
||||
|
||||
<Spacer height="30px" />
|
||||
<AppsHomeDesktop myName={myName} availableQapps={availableQapps} setMode={setMode} myApp={myApp} myWebsite={myWebsite} />
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
height: "100vh",
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
<Spacer height="30px" />
|
||||
<AppsHomeDesktop
|
||||
myName={myName}
|
||||
availableQapps={availableQapps}
|
||||
setMode={setMode}
|
||||
myApp={myApp}
|
||||
myWebsite={myWebsite}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<AppsLibraryDesktop
|
||||
|
||||
<AppsLibraryDesktop
|
||||
isShow={mode === "library" && !selectedTab}
|
||||
availableQapps={availableQapps}
|
||||
setMode={setMode}
|
||||
myName={myName}
|
||||
hasPublishApp={!!(myApp || myWebsite)}
|
||||
categories={categories}
|
||||
getQapps={getQapps}
|
||||
/>
|
||||
|
||||
{mode === "appInfo" && !selectedTab && <AppInfo app={selectedAppInfo} myName={myName} />}
|
||||
{mode === "appInfo-from-category" && !selectedTab && <AppInfo app={selectedAppInfo} myName={myName} />}
|
||||
<AppsCategoryDesktop availableQapps={availableQapps} isShow={mode === 'category' && !selectedTab} category={selectedCategory} myName={myName} />
|
||||
{mode === "publish" && !selectedTab && <AppPublish names={myName ? [myName] : []} categories={categories} />}
|
||||
availableQapps={availableQapps}
|
||||
setMode={setMode}
|
||||
myName={myName}
|
||||
hasPublishApp={!!(myApp || myWebsite)}
|
||||
categories={categories}
|
||||
getQapps={getQapps}
|
||||
/>
|
||||
|
||||
{mode === "appInfo" && !selectedTab && (
|
||||
<AppInfo app={selectedAppInfo} myName={myName} />
|
||||
)}
|
||||
{mode === "appInfo-from-category" && !selectedTab && (
|
||||
<AppInfo app={selectedAppInfo} myName={myName} />
|
||||
)}
|
||||
<AppsCategoryDesktop
|
||||
availableQapps={availableQapps}
|
||||
isShow={mode === "category" && !selectedTab}
|
||||
category={selectedCategory}
|
||||
myName={myName}
|
||||
/>
|
||||
{mode === "publish" && !selectedTab && (
|
||||
<AppPublish names={myName ? [myName] : []} categories={categories} />
|
||||
)}
|
||||
{tabs.map((tab) => {
|
||||
if (!iframeRefs.current[tab.tabId]) {
|
||||
iframeRefs.current[tab.tabId] = React.createRef();
|
||||
}
|
||||
return (
|
||||
<AppViewerContainer
|
||||
key={tab?.tabId}
|
||||
key={tab?.tabId}
|
||||
hide={isNewTabWindow}
|
||||
isSelected={tab?.tabId === selectedTab?.tabId}
|
||||
app={tab}
|
||||
@@ -487,16 +513,23 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
||||
|
||||
{isNewTabWindow && mode === "viewer" && (
|
||||
<>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
overflow: 'auto'
|
||||
}}>
|
||||
|
||||
<Spacer height="30px" />
|
||||
<AppsHomeDesktop myName={myName} availableQapps={availableQapps} setMode={setMode} myApp={myApp} myWebsite={myWebsite} />
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
height: "100vh",
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
<Spacer height="30px" />
|
||||
<AppsHomeDesktop
|
||||
myName={myName}
|
||||
availableQapps={availableQapps}
|
||||
setMode={setMode}
|
||||
myApp={myApp}
|
||||
myWebsite={myWebsite}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
@@ -1,120 +1,122 @@
|
||||
import React, { useMemo, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
AppCircle,
|
||||
AppCircleContainer,
|
||||
AppCircleLabel,
|
||||
AppLibrarySubTitle,
|
||||
AppsContainer,
|
||||
AppsParent,
|
||||
} from "./Apps-styles";
|
||||
import { Avatar, Box, ButtonBase, Input } from "@mui/material";
|
||||
import { Box, ButtonBase, Input } from "@mui/material";
|
||||
import { Add } from "@mui/icons-material";
|
||||
import { getBaseApiReact, isMobile } from "../../App";
|
||||
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||
import { isMobile } from "../../App";
|
||||
import { executeEvent } from "../../utils/events";
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { SortablePinnedApps } from "./SortablePinnedApps";
|
||||
import { extractComponents } from "../Chat/MessageDisplay";
|
||||
import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
|
||||
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
|
||||
import { AppsPrivate } from "./AppsPrivate";
|
||||
import ThemeSelector from "../Theme/ThemeSelector";
|
||||
export const AppsHomeDesktop = ({
|
||||
setMode,
|
||||
myApp,
|
||||
myWebsite,
|
||||
availableQapps,
|
||||
myName
|
||||
myName,
|
||||
}) => {
|
||||
const [qortalUrl, setQortalUrl] = useState('')
|
||||
const [qortalUrl, setQortalUrl] = useState("");
|
||||
|
||||
const openQortalUrl = ()=> {
|
||||
const openQortalUrl = () => {
|
||||
try {
|
||||
if(!qortalUrl) return
|
||||
if (!qortalUrl) return;
|
||||
const res = extractComponents(qortalUrl);
|
||||
if (res) {
|
||||
const { service, name, identifier, path } = res;
|
||||
executeEvent("addTab", { data: { service, name, identifier, path } });
|
||||
executeEvent("open-apps-mode", { });
|
||||
setQortalUrl('qortal://')
|
||||
executeEvent("open-apps-mode", {});
|
||||
setQortalUrl("qortal://");
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<AppsContainer
|
||||
sx={{
|
||||
|
||||
justifyContent: "flex-start",
|
||||
}}
|
||||
>
|
||||
<AppLibrarySubTitle
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
}}
|
||||
>
|
||||
Apps Dashboard
|
||||
</AppLibrarySubTitle>
|
||||
</AppsContainer>
|
||||
<Spacer height="20px" />
|
||||
<AppsContainer
|
||||
sx={{
|
||||
|
||||
justifyContent: "flex-start",
|
||||
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#1f2023',
|
||||
padding: '7px',
|
||||
borderRadius: '20px',
|
||||
width: '100%',
|
||||
maxWidth: '500px'
|
||||
}}>
|
||||
<Input
|
||||
id="standard-adornment-name"
|
||||
value={qortalUrl}
|
||||
onChange={(e) => {
|
||||
setQortalUrl(e.target.value)
|
||||
}}
|
||||
disableUnderline
|
||||
autoComplete='off'
|
||||
autoCorrect='off'
|
||||
placeholder="qortal://"
|
||||
<AppLibrarySubTitle
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
}}
|
||||
>
|
||||
Apps Dashboard
|
||||
</AppLibrarySubTitle>
|
||||
</AppsContainer>
|
||||
|
||||
<Spacer height="20px" />
|
||||
|
||||
<AppsContainer
|
||||
sx={{
|
||||
justifyContent: "flex-start",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#1f2023",
|
||||
padding: "7px",
|
||||
borderRadius: "20px",
|
||||
width: "100%",
|
||||
maxWidth: "500px",
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
id="standard-adornment-name"
|
||||
value={qortalUrl}
|
||||
onChange={(e) => {
|
||||
setQortalUrl(e.target.value);
|
||||
}}
|
||||
disableUnderline
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
placeholder="qortal://"
|
||||
sx={{
|
||||
width: "100%",
|
||||
color: "white",
|
||||
"& .MuiInput-input::placeholder": {
|
||||
color: "rgba(84, 84, 84, 0.70) !important",
|
||||
fontSize: "20px",
|
||||
fontStyle: "normal",
|
||||
fontWeight: 400,
|
||||
lineHeight: "120%", // 24px
|
||||
letterSpacing: "0.15px",
|
||||
opacity: 1,
|
||||
},
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
// Add any additional styles for the input here
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" && qortalUrl) {
|
||||
openQortalUrl();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ButtonBase onClick={() => openQortalUrl()}>
|
||||
<ArrowOutwardIcon
|
||||
sx={{
|
||||
width: '100%',
|
||||
color: 'white',
|
||||
'& .MuiInput-input::placeholder': {
|
||||
color: 'rgba(84, 84, 84, 0.70) !important',
|
||||
fontSize: '20px',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 400,
|
||||
lineHeight: '120%', // 24px
|
||||
letterSpacing: '0.15px',
|
||||
opacity: 1
|
||||
},
|
||||
'&:focus': {
|
||||
outline: 'none',
|
||||
},
|
||||
// Add any additional styles for the input here
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && qortalUrl) {
|
||||
openQortalUrl();
|
||||
}
|
||||
color: qortalUrl ? "white" : "rgba(84, 84, 84, 0.70)",
|
||||
}}
|
||||
/>
|
||||
<ButtonBase onClick={()=> openQortalUrl()}>
|
||||
<ArrowOutwardIcon sx={{
|
||||
color: qortalUrl ? 'white' : 'rgba(84, 84, 84, 0.70)'
|
||||
}} />
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</AppsContainer>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</AppsContainer>
|
||||
|
||||
<Spacer height="45px" />
|
||||
|
||||
<AppsContainer
|
||||
sx={{
|
||||
gap: "50px",
|
||||
@@ -137,7 +139,9 @@ export const AppsHomeDesktop = ({
|
||||
<AppCircleLabel>Library</AppCircleLabel>
|
||||
</AppCircleContainer>
|
||||
</ButtonBase>
|
||||
<AppsPrivate myName={myName} />
|
||||
|
||||
<AppsPrivate myName={myName} />
|
||||
|
||||
<SortablePinnedApps
|
||||
isDesktop={true}
|
||||
availableQapps={availableQapps}
|
||||
@@ -145,6 +149,8 @@ export const AppsHomeDesktop = ({
|
||||
myApp={myApp}
|
||||
/>
|
||||
</AppsContainer>
|
||||
|
||||
<ThemeSelector style={{ position: "fixed", bottom: "1%", left: "0%" }} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -58,7 +58,7 @@ const ScrollerStyled = styled('div')({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled('div')({
|
||||
@@ -77,7 +77,7 @@ const ScrollerStyled = styled('div')({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow, categories={categories} }) => {
|
||||
@@ -290,7 +290,7 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
}}>
|
||||
{categories?.map((category)=> {
|
||||
return (
|
||||
|
@@ -74,7 +74,7 @@ const ScrollerStyled = styled("div")({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled("div")({
|
||||
@@ -93,7 +93,7 @@ const StyledVirtuosoContainer = styled("div")({
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-ms-overflow-style": "none",
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
export const AppsLibraryDesktop = ({
|
||||
|
@@ -1,41 +1,43 @@
|
||||
import React from 'react'
|
||||
import { TabParent } from './Apps-styles'
|
||||
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";
|
||||
import LockIcon from "@mui/icons-material/Lock";
|
||||
|
||||
const TabComponent = ({isSelected, app}) => {
|
||||
const TabComponent = ({ isSelected, app }) => {
|
||||
return (
|
||||
<ButtonBase onClick={()=> {
|
||||
if(isSelected){
|
||||
executeEvent('removeTab', {
|
||||
data: app
|
||||
})
|
||||
return
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
if (isSelected) {
|
||||
executeEvent("removeTab", {
|
||||
data: app,
|
||||
});
|
||||
return;
|
||||
}
|
||||
executeEvent('setSelectedTab', {
|
||||
data: app
|
||||
})
|
||||
}}>
|
||||
<TabParent sx={{
|
||||
border: isSelected && '1px solid #FFFFFF'
|
||||
}}>
|
||||
executeEvent("setSelectedTab", {
|
||||
data: app,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<TabParent
|
||||
sx={{
|
||||
border: isSelected && "1px solid #FFFFFF",
|
||||
}}
|
||||
>
|
||||
{isSelected && (
|
||||
|
||||
<img style={
|
||||
{
|
||||
position: 'absolute',
|
||||
top: '-5px',
|
||||
right: '-5px',
|
||||
zIndex: 1
|
||||
}
|
||||
} src={NavCloseTab}/>
|
||||
|
||||
) }
|
||||
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
|
||||
<img
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-5px",
|
||||
right: "-5px",
|
||||
zIndex: 1,
|
||||
}}
|
||||
src={NavCloseTab}
|
||||
/>
|
||||
)}
|
||||
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
|
||||
<LockIcon
|
||||
sx={{
|
||||
height: "28px",
|
||||
@@ -49,9 +51,13 @@ const TabComponent = ({isSelected, app}) => {
|
||||
width: "28px",
|
||||
}}
|
||||
alt={app?.name}
|
||||
src={app?.privateAppProperties?.logo ? app?.privateAppProperties?.logo :`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
app?.name
|
||||
}/qortal_avatar?async=true`}
|
||||
src={
|
||||
app?.privateAppProperties?.logo
|
||||
? app?.privateAppProperties?.logo
|
||||
: `${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
app?.name
|
||||
}/qortal_avatar?async=true`
|
||||
}
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
@@ -63,9 +69,9 @@ const TabComponent = ({isSelected, app}) => {
|
||||
/>
|
||||
</Avatar>
|
||||
)}
|
||||
</TabParent>
|
||||
</TabParent>
|
||||
</ButtonBase>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default TabComponent
|
||||
export default TabComponent;
|
||||
|
@@ -74,7 +74,6 @@ const {getIndividualUserInfo} = useContext(MyContext)
|
||||
const [selectedReaction, setSelectedReaction] = useState(null);
|
||||
const [userInfo, setUserInfo] = useState(null)
|
||||
|
||||
|
||||
useEffect(()=> {
|
||||
const getInfo = async ()=> {
|
||||
if(!message?.sender) return
|
||||
|
@@ -1,59 +1,59 @@
|
||||
.lineHeight {
|
||||
line-height: 33%;
|
||||
}
|
||||
.lineHeight {
|
||||
line-height: 33%;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
.tooltip {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tooltip .bottom {
|
||||
min-width: 225px;
|
||||
max-width: 250px;
|
||||
top: 35px;
|
||||
right: 0px;
|
||||
/* transform: translate(-50%, 0); */
|
||||
padding: 10px 10px;
|
||||
color: var(--black);
|
||||
background-color: var(--bg-2);
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
border-radius: 8px;
|
||||
position: absolute;
|
||||
z-index: 99999999;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid var(--black);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.tooltip .bottom {
|
||||
min-width: 225px;
|
||||
max-width: 250px;
|
||||
top: 35px;
|
||||
right: 0px;
|
||||
/* transform: translate(-50%, 0); */
|
||||
padding: 10px 10px;
|
||||
color: var(--black);
|
||||
background-color: var(--bg-2);
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
border-radius: 8px;
|
||||
position: absolute;
|
||||
z-index: 99999999;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid var(--black);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.tooltip:hover .bottom {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
z-index: 100;
|
||||
}
|
||||
.tooltip:hover .bottom {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tooltip .bottom i {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -12px;
|
||||
width: 24px;
|
||||
height: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.tooltip .bottom i {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -12px;
|
||||
width: 24px;
|
||||
height: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tooltip .bottom i::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%) rotate(45deg);
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--black);
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.tooltip .bottom i::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%) rotate(45deg);
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--black);
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
@@ -1,17 +1,6 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
BottomNavigation,
|
||||
BottomNavigationAction,
|
||||
ButtonBase,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { Home, Groups, Message, ShowChart } from "@mui/icons-material";
|
||||
import { ButtonBase, Typography, useTheme } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import BottomLogo from "../../assets/svgs/BottomLogo5.svg";
|
||||
import { CustomSvg } from "../../common/CustomSvg";
|
||||
import { WalletIcon } from "../../assets/Icons/WalletIcon";
|
||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||
import { TradingIcon } from "../../assets/Icons/TradingIcon";
|
||||
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||
import AppIcon from "../../assets/svgs/AppIcon.svg";
|
||||
|
||||
@@ -20,19 +9,31 @@ import { Save } from "../Save/Save";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { enabledDevModeAtom } from "../../atoms/global";
|
||||
|
||||
export const IconWrapper = ({ children, label, color, selected, disableWidth, customWidth }) => {
|
||||
export const IconWrapper = ({
|
||||
children,
|
||||
label,
|
||||
color,
|
||||
selected,
|
||||
disableWidth,
|
||||
customWidth,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: "5px",
|
||||
gap: "5px",
|
||||
flexDirection: "column",
|
||||
height: customWidth ? customWidth : disableWidth ? 'auto' : "89px",
|
||||
width: customWidth? customWidth : disableWidth ? 'auto' : "89px",
|
||||
height: customWidth ? customWidth : disableWidth ? "auto" : "89px",
|
||||
width: customWidth ? customWidth : disableWidth ? "auto" : "89px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: selected ? "rgba(28, 29, 32, 1)" : "transparent",
|
||||
backgroundColor: selected
|
||||
? theme.palette.background.default
|
||||
: "transparent",
|
||||
color: color ? color : theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
@@ -41,7 +42,7 @@ export const IconWrapper = ({ children, label, color, selected, disableWidth, cu
|
||||
fontFamily: "Inter",
|
||||
fontSize: "12px",
|
||||
fontWeight: 500,
|
||||
color: color,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
@@ -51,24 +52,7 @@ export const IconWrapper = ({ children, label, color, selected, disableWidth, cu
|
||||
};
|
||||
|
||||
export const DesktopFooter = ({
|
||||
selectedGroup,
|
||||
groupSection,
|
||||
isUnread,
|
||||
goToAnnouncements,
|
||||
isUnreadChat,
|
||||
goToChat,
|
||||
goToThreads,
|
||||
setOpenManageMembers,
|
||||
groupChatHasUnread,
|
||||
groupsAnnHasUnread,
|
||||
directChatHasUnread,
|
||||
chatMode,
|
||||
openDrawerGroups,
|
||||
goToHome,
|
||||
setIsOpenDrawerProfile,
|
||||
mobileViewMode,
|
||||
setMobileViewMode,
|
||||
setMobileViewModeKeepOpen,
|
||||
hasUnreadGroups,
|
||||
hasUnreadDirects,
|
||||
isHome,
|
||||
@@ -77,15 +61,14 @@ export const DesktopFooter = ({
|
||||
setDesktopSideView,
|
||||
isApps,
|
||||
setDesktopViewMode,
|
||||
desktopViewMode,
|
||||
hide,
|
||||
setIsOpenSideViewDirects,
|
||||
setIsOpenSideViewGroups
|
||||
|
||||
setIsOpenSideViewGroups,
|
||||
}) => {
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] =
|
||||
useRecoilState(enabledDevModeAtom);
|
||||
|
||||
if(hide) return
|
||||
if (hide) return;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -110,42 +93,31 @@ export const DesktopFooter = ({
|
||||
goToHome();
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Home"
|
||||
selected={isHome}
|
||||
>
|
||||
<IconWrapper label="Home" selected={isHome}>
|
||||
<HomeIcon
|
||||
height={30}
|
||||
color={isHome ? "white" : "rgba(250, 250, 250, 0.5)"}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('apps')
|
||||
setIsOpenSideViewDirects(false)
|
||||
setIsOpenSideViewGroups(false)
|
||||
setDesktopViewMode("apps");
|
||||
setIsOpenSideViewDirects(false);
|
||||
setIsOpenSideViewGroups(false);
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Apps"
|
||||
selected={isApps}
|
||||
>
|
||||
<img src={AppIcon} />
|
||||
<IconWrapper label="Apps" selected={isApps}>
|
||||
<img src={AppIcon} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopSideView("groups");
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Groups"
|
||||
selected={isGroups}
|
||||
>
|
||||
<IconWrapper label="Groups" selected={isGroups}>
|
||||
<HubsIcon
|
||||
height={30}
|
||||
color={
|
||||
@@ -158,16 +130,13 @@ export const DesktopFooter = ({
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopSideView("directs");
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Messaging"
|
||||
selected={isDirects}
|
||||
>
|
||||
<IconWrapper label="Messaging" selected={isDirects}>
|
||||
<MessagingIcon
|
||||
height={30}
|
||||
color={
|
||||
@@ -180,26 +149,21 @@ export const DesktopFooter = ({
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
|
||||
<Save isDesktop />
|
||||
{isEnabledDevMode && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('dev')
|
||||
setIsOpenSideViewDirects(false)
|
||||
setIsOpenSideViewGroups(false)
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Dev Mode"
|
||||
selected={isApps}
|
||||
onClick={() => {
|
||||
setDesktopViewMode("dev");
|
||||
setIsOpenSideViewDirects(false);
|
||||
setIsOpenSideViewGroups(false);
|
||||
}}
|
||||
>
|
||||
<img src={AppIcon} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
<IconWrapper label="Dev Mode" selected={isApps}>
|
||||
<img src={AppIcon} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
)}
|
||||
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
@@ -1,86 +1,104 @@
|
||||
import { Box, ButtonBase } from '@mui/material';
|
||||
import React from 'react'
|
||||
import { Box, ButtonBase, useTheme } from "@mui/material";
|
||||
import { HomeIcon } from "../assets/Icons/HomeIcon";
|
||||
import { MessagingIcon } from "../assets/Icons/MessagingIcon";
|
||||
import { Save } from "./Save/Save";
|
||||
import { HubsIcon } from "../assets/Icons/HubsIcon";
|
||||
import { CoreSyncStatus } from "./CoreSyncStatus";
|
||||
import { IconWrapper } from './Desktop/DesktopFooter';
|
||||
import AppIcon from "./../assets/svgs/AppIcon.svg";
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { enabledDevModeAtom } from '../atoms/global';
|
||||
import { AppsIcon } from '../assets/Icons/AppsIcon';
|
||||
import { IconWrapper } from "./Desktop/DesktopFooter";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { enabledDevModeAtom } from "../atoms/global";
|
||||
import { AppsIcon } from "../assets/Icons/AppsIcon";
|
||||
import ThemeSelector from "./Theme/ThemeSelector";
|
||||
|
||||
export const DesktopSideBar = ({goToHome, setDesktopSideView, toggleSideViewDirects, hasUnreadDirects, isDirects, toggleSideViewGroups,hasUnreadGroups, isGroups, isApps, setDesktopViewMode, desktopViewMode, myName }) => {
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
|
||||
export const DesktopSideBar = ({
|
||||
goToHome,
|
||||
setDesktopSideView,
|
||||
toggleSideViewDirects,
|
||||
hasUnreadDirects,
|
||||
isDirects,
|
||||
toggleSideViewGroups,
|
||||
hasUnreadGroups,
|
||||
isGroups,
|
||||
isApps,
|
||||
setDesktopViewMode,
|
||||
desktopViewMode,
|
||||
myName,
|
||||
}) => {
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] =
|
||||
useRecoilState(enabledDevModeAtom);
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
width: '60px',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
gap: '25px'
|
||||
}}>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
paddingTop: '23px'
|
||||
}}
|
||||
onClick={() => {
|
||||
goToHome();
|
||||
|
||||
}}
|
||||
>
|
||||
|
||||
<HomeIcon
|
||||
height={34}
|
||||
color={desktopViewMode === 'home' ? 'white': "rgba(250, 250, 250, 0.5)"}
|
||||
|
||||
/>
|
||||
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('apps')
|
||||
// setIsOpenSideViewDirects(false)
|
||||
// setIsOpenSideViewGroups(false)
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={isApps ? 'white' : "rgba(250, 250, 250, 0.5)"}
|
||||
label="Apps"
|
||||
selected={isApps}
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon color={isApps ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('chat')
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "60px",
|
||||
flexDirection: "column",
|
||||
height: "100vh",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
gap: "25px",
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
width: "60px",
|
||||
height: "60px",
|
||||
paddingTop: "23px",
|
||||
}}
|
||||
onClick={() => {
|
||||
goToHome();
|
||||
}}
|
||||
>
|
||||
<HomeIcon
|
||||
height={34}
|
||||
color={
|
||||
desktopViewMode === "home" ? "white" : "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("apps");
|
||||
// setIsOpenSideViewDirects(false)
|
||||
// setIsOpenSideViewGroups(false)
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={(hasUnreadDirects || hasUnreadGroups) ? "var(--unread)" : desktopViewMode === 'chat' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||
label="Chat"
|
||||
disableWidth
|
||||
>
|
||||
<MessagingIcon
|
||||
height={30}
|
||||
color={
|
||||
(hasUnreadDirects || hasUnreadGroups)
|
||||
? "var(--unread)"
|
||||
: desktopViewMode === 'chat'
|
||||
? "white"
|
||||
: "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
{/* <ButtonBase
|
||||
color={isApps ? "white" : "rgba(250, 250, 250, 0.5)"}
|
||||
label="Apps"
|
||||
selected={isApps}
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon
|
||||
color={isApps ? "white" : "rgba(250, 250, 250, 0.5)"}
|
||||
height={30}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("chat");
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--unread)"
|
||||
: theme.palette.text.primary
|
||||
}
|
||||
label="Chat"
|
||||
disableWidth
|
||||
>
|
||||
<MessagingIcon
|
||||
height={30}
|
||||
color={
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--unread)"
|
||||
: theme.palette.text.primary
|
||||
}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
{/* <ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopSideView("groups");
|
||||
toggleSideViewGroups()
|
||||
@@ -98,23 +116,29 @@ export const DesktopSideBar = ({goToHome, setDesktopSideView, toggleSideViewDire
|
||||
/>
|
||||
|
||||
</ButtonBase> */}
|
||||
<Save isDesktop disableWidth myName={myName} />
|
||||
{/* <CoreSyncStatus imageSize="30px" position="left" /> */}
|
||||
{isEnabledDevMode && (
|
||||
<ButtonBase
|
||||
<Save isDesktop disableWidth myName={myName} />
|
||||
{/* <CoreSyncStatus imageSize="30px" position="left" /> */}
|
||||
{isEnabledDevMode && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode('dev')
|
||||
setDesktopViewMode("dev");
|
||||
}}
|
||||
>
|
||||
<IconWrapper
|
||||
color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"}
|
||||
color={
|
||||
desktopViewMode === "dev" ? "white" : "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
label="Dev"
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} />
|
||||
<AppsIcon
|
||||
height={30}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
)}
|
||||
|
||||
<ThemeSelector style={{ position: "fixed", bottom: "1%" }} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -1,71 +1,70 @@
|
||||
.ql-editor {
|
||||
min-height: 200px;
|
||||
width: 100%;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
font-family: Roboto;
|
||||
max-height: 225px;
|
||||
overflow-y: scroll;
|
||||
padding: 0px !important;
|
||||
}
|
||||
min-height: 200px;
|
||||
width: 100%;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
font-family: Roboto;
|
||||
max-height: 225px;
|
||||
overflow-y: scroll;
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.ql-editor::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
.ql-editor::-webkit-scrollbar-track:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.ql-editor::-webkit-scrollbar {
|
||||
width: 16px;
|
||||
height: 10px;
|
||||
background-color: rgba(229, 229, 229, 0.70);
|
||||
}
|
||||
|
||||
.ql-editor::-webkit-scrollbar-thumb {
|
||||
background-color: #B0B0B0;
|
||||
border-radius: 8px;
|
||||
background-clip: content-box;
|
||||
border: 4px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
.ql-editor img {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ql-editor-display {
|
||||
min-height: 20px;
|
||||
width: 100%;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
font-family: Roboto;
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.ql-editor-display img {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ql-container {
|
||||
font-size: 16px
|
||||
}
|
||||
.ql-editor::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
.ql-editor::-webkit-scrollbar-track:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.ql-toolbar .ql-stroke {
|
||||
fill: none !important;
|
||||
stroke: black !important;
|
||||
.ql-editor::-webkit-scrollbar {
|
||||
width: 16px;
|
||||
height: 10px;
|
||||
background-color: rgba(229, 229, 229, 0.7);
|
||||
}
|
||||
|
||||
.ql-editor::-webkit-scrollbar-thumb {
|
||||
background-color: #b0b0b0;
|
||||
border-radius: 8px;
|
||||
background-clip: content-box;
|
||||
border: 4px solid transparent;
|
||||
}
|
||||
|
||||
.ql-editor img {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ql-editor-display {
|
||||
min-height: 20px;
|
||||
width: 100%;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
font-family: Roboto;
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.ql-editor-display img {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ql-container {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ql-toolbar .ql-stroke {
|
||||
fill: none !important;
|
||||
stroke: black !important;
|
||||
}
|
||||
|
||||
.ql-toolbar .ql-fill {
|
||||
fill: black !important;
|
||||
stroke: none !important;
|
||||
fill: black !important;
|
||||
stroke: none !important;
|
||||
}
|
||||
|
||||
.ql-toolbar .ql-picker {
|
||||
color: black !important;
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.ql-toolbar .ql-picker-options {
|
||||
background-color: white !important;
|
||||
}
|
||||
background-color: white !important;
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||
import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2";
|
||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||
import { Save } from "../Save/Save";
|
||||
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';
|
||||
import CloseFullscreenIcon from "@mui/icons-material/CloseFullscreen";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { fullScreenAtom, hasSettingsChangedAtom } from "../../atoms/global";
|
||||
import { useAppFullScreen } from "../../useAppFullscreen";
|
||||
@@ -36,12 +36,12 @@ const Header = ({
|
||||
setMobileViewMode,
|
||||
myName,
|
||||
setSelectedDirect,
|
||||
setNewChat
|
||||
setNewChat,
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const open = Boolean(anchorEl);
|
||||
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
|
||||
const {exitFullScreen} = useAppFullScreen(setFullScreen)
|
||||
const { exitFullScreen } = useAppFullScreen(setFullScreen);
|
||||
const handleClick = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
@@ -77,34 +77,39 @@ const Header = ({
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
|
||||
|
||||
|
||||
onClick={() => {
|
||||
setMobileViewModeKeepOpen("");
|
||||
goToHome();
|
||||
}}
|
||||
// onClick={onHomeClick}
|
||||
>
|
||||
<HomeIcon height={20} width={27} color="rgba(145, 145, 147, 1)" />
|
||||
<HomeIcon height={20} width={27} />
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
|
||||
onClick={handleClick}
|
||||
>
|
||||
<NotificationIcon height={20} width={21} color={hasUnreadDirects || hasUnreadGroups ? "var(--danger)" : "rgba(145, 145, 147, 1)"} />
|
||||
<ButtonBase onClick={handleClick}>
|
||||
<NotificationIcon
|
||||
height={20}
|
||||
width={21}
|
||||
color={
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--danger)"
|
||||
: "rgba(145, 145, 147, 1)"
|
||||
}
|
||||
/>
|
||||
</ButtonBase>
|
||||
{fullScreen && (
|
||||
<ButtonBase onClick={()=> {
|
||||
exitFullScreen()
|
||||
setFullScreen(false)
|
||||
}}>
|
||||
<CloseFullscreenIcon sx={{
|
||||
color: 'rgba(145, 145, 147, 1)'
|
||||
}} />
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
exitFullScreen();
|
||||
setFullScreen(false);
|
||||
}}
|
||||
>
|
||||
<CloseFullscreenIcon
|
||||
sx={{
|
||||
color: "rgba(145, 145, 147, 1)",
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
)}
|
||||
|
||||
</Box>
|
||||
|
||||
{/* Center Title */}
|
||||
@@ -135,14 +140,15 @@ const Header = ({
|
||||
setMobileViewModeKeepOpen("messaging");
|
||||
}}
|
||||
>
|
||||
<MessagingIcon2 height={20} color={hasUnreadDirects ? "var(--danger)" : "rgba(145, 145, 147, 1)"}
|
||||
|
||||
<MessagingIcon2
|
||||
height={20}
|
||||
color={
|
||||
hasUnreadDirects ? "var(--danger)" : "rgba(145, 145, 147, 1)"
|
||||
}
|
||||
/>
|
||||
</ButtonBase>
|
||||
<Save />
|
||||
<ButtonBase
|
||||
onClick={logoutFunc}
|
||||
>
|
||||
<ButtonBase onClick={logoutFunc}>
|
||||
<LogoutIcon
|
||||
height={20}
|
||||
width={21}
|
||||
@@ -152,83 +158,104 @@ const Header = ({
|
||||
</Box>
|
||||
</Toolbar>
|
||||
<Menu
|
||||
id="home-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
MenuListProps={{
|
||||
"aria-labelledby": "basic-button",
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
|
||||
id="home-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
MenuListProps={{
|
||||
"aria-labelledby": "basic-button",
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
backgroundColor: 'var(--bg-primary)',
|
||||
color: '#fff',
|
||||
width: '148px',
|
||||
borderRadius: '5px'
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
color: "#fff",
|
||||
width: "148px",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
},
|
||||
|
||||
}}
|
||||
sx={{
|
||||
marginTop: '10px'
|
||||
}}
|
||||
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setSelectedDirect(null)
|
||||
setNewChat(false)
|
||||
setMobileViewMode("groups");
|
||||
setMobileViewModeKeepOpen("")
|
||||
handleClose();
|
||||
marginTop: "10px",
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<HubsIcon height={20} color={hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"
|
||||
},
|
||||
}} primary="Groups" />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setMobileViewModeKeepOpen("messaging");
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setSelectedDirect(null);
|
||||
setNewChat(false);
|
||||
setMobileViewMode("groups");
|
||||
setMobileViewModeKeepOpen("");
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: "24px !important",
|
||||
}}
|
||||
>
|
||||
<HubsIcon
|
||||
height={20}
|
||||
color={
|
||||
hasUnreadGroups ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadGroups
|
||||
? "var(--danger)"
|
||||
: "rgba(250, 250, 250, 0.5)",
|
||||
},
|
||||
}}
|
||||
primary="Groups"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setMobileViewModeKeepOpen("messaging");
|
||||
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"
|
||||
},
|
||||
}} primary="Messaging" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: "24px !important",
|
||||
}}
|
||||
>
|
||||
<MessagingIcon
|
||||
height={20}
|
||||
color={
|
||||
hasUnreadDirects
|
||||
? "var(--danger)"
|
||||
: "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects
|
||||
? "var(--danger)"
|
||||
: "rgba(250, 250, 250, 0.5)",
|
||||
},
|
||||
}}
|
||||
primary="Messaging"
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</AppBar>
|
||||
);
|
||||
}
|
||||
@@ -255,24 +282,27 @@ const Header = ({
|
||||
width: "75px",
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
|
||||
onClick={goToHome}
|
||||
// onClick={onHomeClick}
|
||||
>
|
||||
<HomeIcon color="rgba(145, 145, 147, 1)" />
|
||||
</ButtonBase>
|
||||
{fullScreen && (
|
||||
<ButtonBase onClick={()=> {
|
||||
exitFullScreen()
|
||||
setFullScreen(false)
|
||||
}}>
|
||||
<CloseFullscreenIcon sx={{
|
||||
color: 'rgba(145, 145, 147, 1)'
|
||||
}} />
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={goToHome}
|
||||
// onClick={onHomeClick}
|
||||
>
|
||||
<HomeIcon />
|
||||
</ButtonBase>
|
||||
{fullScreen && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
exitFullScreen();
|
||||
setFullScreen(false);
|
||||
}}
|
||||
>
|
||||
<CloseFullscreenIcon
|
||||
sx={{
|
||||
color: "rgba(145, 145, 147, 1)",
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
{/* Center Title */}
|
||||
<Typography
|
||||
variant="h6"
|
||||
@@ -294,16 +324,15 @@ const Header = ({
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
{/* Right Logout Icon */}
|
||||
<Save />
|
||||
<ButtonBase
|
||||
onClick={logoutFunc}
|
||||
{/* Right Logout Icon */}
|
||||
<Save />
|
||||
<ButtonBase
|
||||
onClick={logoutFunc}
|
||||
|
||||
|
||||
// onClick={onLogoutClick}
|
||||
>
|
||||
<LogoutIcon color="rgba(145, 145, 147, 1)" />
|
||||
</ButtonBase>
|
||||
// onClick={onLogoutClick}
|
||||
>
|
||||
<LogoutIcon color="rgba(145, 145, 147, 1)" />
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
@@ -357,8 +386,14 @@ const Header = ({
|
||||
boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.3)", // Optional shadow for the circle
|
||||
}}
|
||||
>
|
||||
<IconButton onClick={handleClick} color="inherit">
|
||||
<NotificationIcon color={hasUnreadDirects || hasUnreadGroups ? "var(--danger)" : "rgba(255, 255, 255, 1)"} />
|
||||
<IconButton onClick={handleClick} color="inherit">
|
||||
<NotificationIcon
|
||||
color={
|
||||
hasUnreadDirects || hasUnreadGroups
|
||||
? "var(--danger)"
|
||||
: "rgba(255, 255, 255, 1)"
|
||||
}
|
||||
/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
@@ -389,6 +424,7 @@ const Header = ({
|
||||
</Box>
|
||||
</ButtonBase> */}
|
||||
</Box>
|
||||
|
||||
<Menu
|
||||
id="home-menu"
|
||||
anchorEl={anchorEl}
|
||||
@@ -398,51 +434,60 @@ const Header = ({
|
||||
"aria-labelledby": "basic-button",
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
backgroundColor: 'var(--bg-primary)',
|
||||
color: '#fff',
|
||||
width: '148px',
|
||||
borderRadius: '5px'
|
||||
},
|
||||
vertical: "bottom",
|
||||
horizontal: "center",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
color: "#fff",
|
||||
width: "148px",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
|
||||
}}
|
||||
sx={{
|
||||
marginTop: '10px'
|
||||
}}
|
||||
|
||||
},
|
||||
}}
|
||||
sx={{
|
||||
marginTop: "10px",
|
||||
}}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setMobileViewMode("groups");
|
||||
setMobileViewModeKeepOpen("")
|
||||
setMobileViewModeKeepOpen("");
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<HubsIcon height={20} color={hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} />
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: "24px !important",
|
||||
}}
|
||||
>
|
||||
<HubsIcon
|
||||
height={20}
|
||||
color={
|
||||
hasUnreadGroups ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"
|
||||
},
|
||||
}} primary="Groups" />
|
||||
<ListItemText
|
||||
sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects
|
||||
? "var(--danger)"
|
||||
: "rgba(250, 250, 250, 0.5)",
|
||||
},
|
||||
}}
|
||||
primary="Groups"
|
||||
/>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setMobileViewModeKeepOpen("messaging");
|
||||
@@ -450,21 +495,32 @@ const Header = ({
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{
|
||||
|
||||
minWidth: '24px !important'
|
||||
}}>
|
||||
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} />
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: "24px !important",
|
||||
}}
|
||||
>
|
||||
<MessagingIcon
|
||||
height={20}
|
||||
color={
|
||||
hasUnreadDirects ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
|
||||
}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"
|
||||
},
|
||||
}} primary="Messaging" />
|
||||
<ListItemText
|
||||
sx={{
|
||||
"& .MuiTypography-root": {
|
||||
fontSize: "12px",
|
||||
fontWeight: 600,
|
||||
color: hasUnreadDirects
|
||||
? "var(--danger)"
|
||||
: "rgba(250, 250, 250, 0.5)",
|
||||
},
|
||||
}}
|
||||
primary="Messaging"
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -1,67 +1,97 @@
|
||||
import { Button, ButtonBase, InputAdornment, TextField, TextFieldProps, styled } from "@mui/material";
|
||||
import { forwardRef, useState } from 'react'
|
||||
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
export const CustomInput = styled(TextField)({
|
||||
width: "183px", // Adjust the width as needed
|
||||
import {
|
||||
ButtonBase,
|
||||
InputAdornment,
|
||||
TextField,
|
||||
TextFieldProps,
|
||||
styled,
|
||||
} from "@mui/material";
|
||||
import { forwardRef, useState } from "react";
|
||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||
|
||||
export const CustomInput = styled(TextField)(({ theme }) => ({
|
||||
width: "183px",
|
||||
borderRadius: "5px",
|
||||
// backgroundColor: "rgba(30, 30, 32, 1)",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
outline: "none",
|
||||
input: {
|
||||
fontSize: 10,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: 400,
|
||||
color: "white",
|
||||
"&::placeholder": {
|
||||
fontSize: 16,
|
||||
color: "rgba(255, 255, 255, 0.2)",
|
||||
},
|
||||
outline: "none",
|
||||
padding: "10px",
|
||||
fontSize: 10,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
"&::placeholder": {
|
||||
fontSize: 16,
|
||||
color: theme.palette.text.disabled,
|
||||
},
|
||||
outline: "none",
|
||||
padding: "10px",
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
"& fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
},
|
||||
"& .MuiInput-underline:before": {
|
||||
borderBottom: "none",
|
||||
borderBottom: "none",
|
||||
},
|
||||
"& .MuiInput-underline:hover:not(.Mui-disabled):before": {
|
||||
borderBottom: "none",
|
||||
borderBottom: "none",
|
||||
},
|
||||
"& .MuiInput-underline:after": {
|
||||
borderBottom: "none",
|
||||
borderBottom: "none",
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>( ({ ...props }, ref) => {
|
||||
export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
({ ...props }, ref) => {
|
||||
const [canViewPassword, setCanViewPassword] = useState(false);
|
||||
return (
|
||||
<CustomInput
|
||||
type={canViewPassword ? 'text' : 'password'}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end" data-testid="toggle-view-password-btn" onClick={() => {
|
||||
setCanViewPassword((prevState) => !prevState)
|
||||
}}>
|
||||
{canViewPassword ? <ButtonBase data-testid="plain-text-indicator" sx={{ minWidth: 0, p: 0 }}><VisibilityOffIcon sx={{
|
||||
color: 'white'
|
||||
}}/></ButtonBase> : <ButtonBase data-testid="password-text-indicator" sx={{ minWidth: 0, p: 0 }}><VisibilityIcon sx={{
|
||||
color: 'white'
|
||||
}} /></ButtonBase>}
|
||||
</InputAdornment>
|
||||
)
|
||||
}}
|
||||
inputRef={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
});
|
||||
<CustomInput
|
||||
type={canViewPassword ? "text" : "password"}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment
|
||||
position="end"
|
||||
data-testid="toggle-view-password-btn"
|
||||
onClick={() => {
|
||||
setCanViewPassword((prevState) => !prevState);
|
||||
}}
|
||||
>
|
||||
{canViewPassword ? (
|
||||
<ButtonBase
|
||||
data-testid="plain-text-indicator"
|
||||
sx={{ minWidth: 0, p: 0 }}
|
||||
>
|
||||
<VisibilityOffIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
) : (
|
||||
<ButtonBase
|
||||
data-testid="password-text-indicator"
|
||||
sx={{ minWidth: 0, p: 0 }}
|
||||
>
|
||||
<VisibilityIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
)}
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
inputRef={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@@ -1,27 +1,26 @@
|
||||
.reaction-container {
|
||||
position: relative; /* Parent must be positioned relatively */
|
||||
}
|
||||
|
||||
.emoji-picker {
|
||||
position: absolute; /* Picker positioned absolutely relative to the parent */
|
||||
right: 0;
|
||||
z-index: 9000000000; /* Ensure picker appears above other content */
|
||||
}
|
||||
|
||||
.message-container {
|
||||
overflow: visible; /* Ensure the message container doesn't cut off the picker */
|
||||
}
|
||||
|
||||
position: relative; /* Parent must be positioned relatively */
|
||||
}
|
||||
|
||||
.reaction-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emoji-picker {
|
||||
overflow: hidden;
|
||||
width: auto
|
||||
}
|
||||
.emoji-picker {
|
||||
position: absolute; /* Picker positioned absolutely relative to the parent */
|
||||
right: 0;
|
||||
z-index: 9000000000; /* Ensure picker appears above other content */
|
||||
}
|
||||
|
||||
.EmojiPickerReact.epr-dark-theme {
|
||||
--epr-emoji-size: 18px; /* Adjust emoji size for dark mode */
|
||||
}
|
||||
.message-container {
|
||||
overflow: visible; /* Ensure the message container doesn't cut off the picker */
|
||||
}
|
||||
|
||||
.reaction-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emoji-picker {
|
||||
overflow: hidden;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.EmojiPickerReact.epr-dark-theme {
|
||||
--epr-emoji-size: 18px; /* Adjust emoji size for dark mode */
|
||||
}
|
||||
|
@@ -22,20 +22,22 @@ import { LoadingButton } from "@mui/lab";
|
||||
import { saveToLocalStorage } from "../Apps/AppsNavBar";
|
||||
import { decryptData, encryptData } from "../../qortalRequests/get";
|
||||
import { saveFileToDiskGeneric } from "../../utils/generateWallet/generateWallet";
|
||||
import { base64ToUint8Array, uint8ArrayToObject } from "../../backgroundFunctions/encryption";
|
||||
|
||||
import {
|
||||
base64ToUint8Array,
|
||||
uint8ArrayToObject,
|
||||
} from "../../backgroundFunctions/encryption";
|
||||
|
||||
export const handleImportClick = async () => {
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.base64,.txt';
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = ".base64,.txt";
|
||||
|
||||
// Create a promise to handle file selection and reading synchronously
|
||||
return await new Promise((resolve, reject) => {
|
||||
fileInput.onchange = () => {
|
||||
const file = fileInput.files[0];
|
||||
if (!file) {
|
||||
reject(new Error('No file selected'));
|
||||
reject(new Error("No file selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,7 +46,7 @@ export const handleImportClick = async () => {
|
||||
resolve(e.target.result); // Resolve with the file content
|
||||
};
|
||||
reader.onerror = () => {
|
||||
reject(new Error('Error reading file'));
|
||||
reject(new Error("Error reading file"));
|
||||
};
|
||||
|
||||
reader.readAsText(file); // Read the file as text (Base64 string)
|
||||
@@ -53,8 +55,7 @@ export const handleImportClick = async () => {
|
||||
// Trigger the file input dialog
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
const [pinnedApps, setPinnedApps] = useRecoilState(sortablePinnedAppsAtom);
|
||||
@@ -65,7 +66,8 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
settingsLocalLastUpdatedAtom
|
||||
);
|
||||
const setHasSettingsChangedAtom = useSetRecoilState(hasSettingsChangedAtom);
|
||||
const [isUsingImportExportSettings, setIsUsingImportExportSettings] = useRecoilState(isUsingImportExportSettingsAtom);
|
||||
const [isUsingImportExportSettings, setIsUsingImportExportSettings] =
|
||||
useRecoilState(isUsingImportExportSettingsAtom);
|
||||
|
||||
const [canSave] = useRecoilState(canSaveSettingToQdnAtom);
|
||||
const [openSnack, setOpenSnack] = useState(false);
|
||||
@@ -104,8 +106,6 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
settingsLocalLastUpdated,
|
||||
]);
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
setHasSettingsChangedAtom(hasChanged);
|
||||
}, [hasChanged]);
|
||||
@@ -176,7 +176,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
message: "Sucessfully published to QDN",
|
||||
});
|
||||
setOpenSnack(true);
|
||||
setAnchorEl(null)
|
||||
setAnchorEl(null);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -197,7 +197,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
const revertChanges = () => {
|
||||
setPinnedApps(oldPinnedApps);
|
||||
saveToLocalStorage("ext_saved_settings", "sortablePinnedApps", null);
|
||||
setAnchorEl(null)
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -207,37 +207,22 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
disabled={
|
||||
// !hasChanged ||
|
||||
// !canSave ||
|
||||
isLoading
|
||||
isLoading
|
||||
// settingsQdnLastUpdated === -100
|
||||
}
|
||||
>
|
||||
{isDesktop ? (
|
||||
<IconWrapper
|
||||
disableWidth={disableWidth}
|
||||
color="rgba(250, 250, 250, 0.5)"
|
||||
label="Save"
|
||||
selected={false}
|
||||
>
|
||||
<SaveIcon
|
||||
color={
|
||||
settingsQdnLastUpdated === -100
|
||||
? "#8F8F91"
|
||||
: hasChanged && !isLoading
|
||||
? "#5EB049"
|
||||
: "#8F8F91"
|
||||
}
|
||||
color={hasChanged && !isLoading ? "#5EB049" : undefined}
|
||||
/>
|
||||
</IconWrapper>
|
||||
) : (
|
||||
<SaveIcon
|
||||
color={
|
||||
settingsQdnLastUpdated === -100
|
||||
? "#8F8F91"
|
||||
: hasChanged && !isLoading
|
||||
? "#5EB049"
|
||||
: "#8F8F91"
|
||||
}
|
||||
/>
|
||||
<SaveIcon color={hasChanged && !isLoading ? "#5EB049" : undefined} />
|
||||
)}
|
||||
</ButtonBase>
|
||||
<Popover
|
||||
@@ -261,15 +246,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
>
|
||||
{isUsingImportExportSettings && (
|
||||
<Box
|
||||
sx={{
|
||||
padding: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
width: '100%'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
padding: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
@@ -286,59 +271,45 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
</Typography>
|
||||
<Spacer height="40px" />
|
||||
<Button
|
||||
size="small"
|
||||
onClick={()=> {
|
||||
saveToLocalStorage("ext_saved_settings_import_export", "sortablePinnedApps", null, true);
|
||||
setIsUsingImportExportSettings(false)
|
||||
}}
|
||||
variant="contained"
|
||||
sx={{
|
||||
size="small"
|
||||
onClick={() => {
|
||||
saveToLocalStorage(
|
||||
"ext_saved_settings_import_export",
|
||||
"sortablePinnedApps",
|
||||
null,
|
||||
true
|
||||
);
|
||||
setIsUsingImportExportSettings(false);
|
||||
}}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
fontWeight: "bold",
|
||||
opacity: 0.7,
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
fontWeight: 'bold',
|
||||
opacity: 0.7,
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Use QDN saving
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Use QDN saving
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{!isUsingImportExportSettings && (
|
||||
<Box
|
||||
<Box
|
||||
sx={{
|
||||
padding: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
width: '100%'
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{!myName ? (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
You need a registered Qortal name to save your pinned apps to QDN.
|
||||
</Typography>
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
{hasChanged && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
@@ -352,213 +323,242 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
You have unsaved changes to your pinned apps. Save them to QDN.
|
||||
You need a registered Qortal name to save your pinned apps to
|
||||
QDN.
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
sx={{
|
||||
backgroundColor: "var(--green)",
|
||||
color: "black",
|
||||
opacity: 0.7,
|
||||
fontWeight: 'bold',
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--green)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={saveToQdn}
|
||||
variant="contained"
|
||||
>
|
||||
Save to QDN
|
||||
</LoadingButton>
|
||||
<Spacer height="20px" />
|
||||
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated > 0 && (
|
||||
<>
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
{hasChanged && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Don't like your current local changes? Would you like to
|
||||
reset to your saved QDN pinned apps?
|
||||
You have unsaved changes to your pinned apps. Save them to
|
||||
QDN.
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={revertChanges}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--danger)",
|
||||
backgroundColor: "var(--green)",
|
||||
color: "black",
|
||||
fontWeight: 'bold',
|
||||
opacity: 0.7,
|
||||
fontWeight: "bold",
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
backgroundColor: "var(--green)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={saveToQdn}
|
||||
variant="contained"
|
||||
>
|
||||
Revert to QDN
|
||||
Save to QDN
|
||||
</LoadingButton>
|
||||
</>
|
||||
<Spacer height="20px" />
|
||||
{!isNaN(settingsQdnLastUpdated) &&
|
||||
settingsQdnLastUpdated > 0 && (
|
||||
<>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Don't like your current local changes? Would you
|
||||
like to reset to your saved QDN pinned apps?
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={revertChanges}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
fontWeight: "bold",
|
||||
opacity: 0.7,
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Revert to QDN
|
||||
</LoadingButton>
|
||||
</>
|
||||
)}
|
||||
{!isNaN(settingsQdnLastUpdated) &&
|
||||
settingsQdnLastUpdated === 0 && (
|
||||
<>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Don't like your current local changes? Would you
|
||||
like to reset to the default pinned apps?
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
onClick={revertChanges}
|
||||
variant="contained"
|
||||
>
|
||||
Revert to default
|
||||
</LoadingButton>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated === 0 && (
|
||||
<>
|
||||
{!isNaN(settingsQdnLastUpdated) &&
|
||||
settingsQdnLastUpdated === -100 &&
|
||||
isUsingImportExportSettings !== true && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
The app was unable to download your existing QDN-saved
|
||||
pinned apps. Would you like to overwrite those changes?
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={saveToQdn}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
fontWeight: "bold",
|
||||
opacity: 0.7,
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Overwrite to QDN
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
)}
|
||||
{!hasChanged && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Don't like your current local changes? Would you like to
|
||||
reset to the default pinned apps?
|
||||
You currently do not have any changes to your pinned apps
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
onClick={revertChanges}
|
||||
variant="contained"
|
||||
>
|
||||
Revert to default
|
||||
</LoadingButton>
|
||||
</>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated === -100 && isUsingImportExportSettings !== true && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
The app was unable to download your existing QDN-saved pinned
|
||||
apps. Would you like to overwrite those changes?
|
||||
</Typography>
|
||||
<Spacer height="10px" />
|
||||
<LoadingButton
|
||||
size="small"
|
||||
loading={isLoading}
|
||||
onClick={saveToQdn}
|
||||
variant="contained"
|
||||
sx={{
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
fontWeight: 'bold',
|
||||
opacity: 0.7,
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
color: "black",
|
||||
opacity: 1,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Overwrite to QDN
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
)}
|
||||
{!hasChanged && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
You currently do not have any changes to your pinned apps
|
||||
</Typography>
|
||||
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
<Box
|
||||
sx={{
|
||||
padding: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
padding: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
width: '100%'
|
||||
gap: "10px",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '10px',
|
||||
justifyContent: 'flex-end',
|
||||
width: '100%'
|
||||
}}>
|
||||
<ButtonBase onClick={async () => {
|
||||
try {
|
||||
const fileContent = await handleImportClick();
|
||||
const decryptedData = await decryptData({
|
||||
encryptedData: fileContent,
|
||||
});
|
||||
const decryptToUnit8ArraySubject =
|
||||
base64ToUint8Array(decryptedData);
|
||||
const responseData = uint8ArrayToObject(
|
||||
decryptToUnit8ArraySubject
|
||||
);
|
||||
if(Array.isArray(responseData)){
|
||||
saveToLocalStorage("ext_saved_settings_import_export", "sortablePinnedApps", responseData, {
|
||||
isUsingImportExport: true
|
||||
});
|
||||
setPinnedApps(responseData)
|
||||
setOldPinnedApps(responseData)
|
||||
setIsUsingImportExportSettings(true)
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
<ButtonBase
|
||||
onClick={async () => {
|
||||
try {
|
||||
const fileContent = await handleImportClick();
|
||||
const decryptedData = await decryptData({
|
||||
encryptedData: fileContent,
|
||||
});
|
||||
const decryptToUnit8ArraySubject =
|
||||
base64ToUint8Array(decryptedData);
|
||||
const responseData = uint8ArrayToObject(
|
||||
decryptToUnit8ArraySubject
|
||||
);
|
||||
if (Array.isArray(responseData)) {
|
||||
saveToLocalStorage(
|
||||
"ext_saved_settings_import_export",
|
||||
"sortablePinnedApps",
|
||||
responseData,
|
||||
{
|
||||
isUsingImportExport: true,
|
||||
}
|
||||
}}>
|
||||
|
||||
Import
|
||||
</ButtonBase>
|
||||
<ButtonBase onClick={async () => {
|
||||
try {
|
||||
const data64 = await objectToBase64(pinnedApps);
|
||||
|
||||
const encryptedData = await encryptData({
|
||||
data64,
|
||||
});
|
||||
const blob = new Blob([encryptedData], {
|
||||
type: "text/plain",
|
||||
});
|
||||
|
||||
const timestamp = new Date()
|
||||
.toISOString()
|
||||
.replace(/:/g, "-"); // Safe timestamp for filenames
|
||||
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
|
||||
await saveFileToDiskGeneric(blob, filename)
|
||||
|
||||
} catch (error) {
|
||||
console.log('error', error)
|
||||
}
|
||||
}}>
|
||||
Export
|
||||
);
|
||||
setPinnedApps(responseData);
|
||||
setOldPinnedApps(responseData);
|
||||
setIsUsingImportExportSettings(true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Import
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</Box>
|
||||
<ButtonBase
|
||||
onClick={async () => {
|
||||
try {
|
||||
const data64 = await objectToBase64(pinnedApps);
|
||||
|
||||
const encryptedData = await encryptData({
|
||||
data64,
|
||||
});
|
||||
const blob = new Blob([encryptedData], {
|
||||
type: "text/plain",
|
||||
});
|
||||
|
||||
const timestamp = new Date().toISOString().replace(/:/g, "-"); // Safe timestamp for filenames
|
||||
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
|
||||
await saveFileToDiskGeneric(blob, filename);
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Export
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</Box>
|
||||
</Popover>
|
||||
<CustomizedSnackbars
|
||||
duration={3500}
|
||||
|
34
src/components/Theme/ThemeContext.tsx
Normal file
34
src/components/Theme/ThemeContext.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { createContext, useContext, useState, useMemo } from 'react';
|
||||
import { createTheme, ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
|
||||
|
||||
const darkTheme = createTheme({
|
||||
palette: {
|
||||
mode: 'dark',
|
||||
},
|
||||
});
|
||||
|
||||
const lightTheme = createTheme({
|
||||
palette: {
|
||||
mode: 'light',
|
||||
},
|
||||
});
|
||||
|
||||
const ThemeContext = createContext({ themeMode: 'light', toggleTheme: () => {} });
|
||||
|
||||
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [themeMode, setThemeMode] = useState('light');
|
||||
|
||||
const theme = useMemo(() => (themeMode === 'light' ? lightTheme : darkTheme), [themeMode]);
|
||||
|
||||
const toggleTheme = () => {
|
||||
setThemeMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ themeMode, toggleTheme }}>
|
||||
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useThemeContext = () => useContext(ThemeContext);
|
77
src/components/Theme/ThemeSelector.tsx
Normal file
77
src/components/Theme/ThemeSelector.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import { useThemeContext } from "./ThemeContext";
|
||||
import { styled, Switch } from "@mui/material";
|
||||
|
||||
const ThemeSwitch = styled(Switch)(({ theme }) => ({
|
||||
width: 62,
|
||||
height: 34,
|
||||
padding: 7,
|
||||
"& .MuiSwitch-switchBase": {
|
||||
margin: 1,
|
||||
padding: 0,
|
||||
transform: "translateX(6px)",
|
||||
"&.Mui-checked": {
|
||||
color: "#fff",
|
||||
transform: "translateX(22px)",
|
||||
"& .MuiSwitch-thumb:before": {
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
"#fff"
|
||||
)}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
|
||||
},
|
||||
"& + .MuiSwitch-track": {
|
||||
opacity: 1,
|
||||
backgroundColor: "#aab4be",
|
||||
...theme.applyStyles("dark", {
|
||||
backgroundColor: "#8796A5",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
"& .MuiSwitch-thumb": {
|
||||
backgroundColor: "#001e3c",
|
||||
width: 32,
|
||||
height: 32,
|
||||
"&::before": {
|
||||
content: "''",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
left: 0,
|
||||
top: 0,
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center",
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
"#fff"
|
||||
)}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
|
||||
},
|
||||
...theme.applyStyles("dark", {
|
||||
backgroundColor: "#003892",
|
||||
}),
|
||||
},
|
||||
"& .MuiSwitch-track": {
|
||||
opacity: 1,
|
||||
backgroundColor: "#aab4be",
|
||||
borderRadius: 20 / 2,
|
||||
...theme.applyStyles("dark", {
|
||||
backgroundColor: "#8796A5",
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
const ThemeSelector = ({ style }) => {
|
||||
const { themeMode, toggleTheme } = useThemeContext();
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "1px",
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
<ThemeSwitch checked={themeMode === "dark"} onChange={toggleTheme} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeSelector;
|
Reference in New Issue
Block a user