Merge pull request #15 from nbenaglia/feature/css-light-and-switch

Add themeSelector and switcher (dark and light styles)
This commit is contained in:
Phillip 2025-04-11 09:40:38 +03:00 committed by GitHub
commit 60474c2867
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 2050 additions and 1707 deletions

View File

@ -2,17 +2,17 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
'react-refresh/only-export-components': [
'off',
"react-refresh/only-export-components": [
"off",
{ allowConstantExport: true },
],
},
}
};

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ lerna-debug.log*
node_modules
dist
dist.zip
dist-ssr
*.local

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
node_modules
build
dist

View File

@ -1,15 +1,15 @@
import type { CapacitorConfig } from '@capacitor/cli';
import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = {
appId: 'org.Qortal.Qortal-Hub',
appName: 'Qortal-Hub',
webDir: 'dist',
"plugins": {
"LocalNotifications": {
"smallIcon": "qort",
"iconColor": "#09b6e8"
}
}
appId: "org.Qortal.Qortal-Hub",
appName: "Qortal-Hub",
webDir: "dist",
plugins: {
LocalNotifications: {
smallIcon: "qort",
iconColor: "#09b6e8",
},
},
};
export default config;

BIN
dist.zip

Binary file not shown.

View File

@ -1,12 +1,9 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Qortal Hub</title>
</head>
<body>

17
package-lock.json generated
View File

@ -106,6 +106,7 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"prettier": "^3.5.3",
"rename-cli": "^6.2.1",
"typescript": "^5.2.2",
"vite": "^5.1.6",
@ -15990,6 +15991,22 @@
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-bytes": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",

View File

@ -6,6 +6,7 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"format": "prettier --write .",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"test": "vitest",
@ -110,6 +111,7 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"prettier": "^3.5.3",
"rename-cli": "^6.2.1",
"typescript": "^5.2.2",
"vite": "^5.1.6",

View File

@ -1,46 +1,49 @@
import {
AppBar,
Button,
Toolbar,
Typography,
Box,
TextField,
InputLabel,
} from "@mui/material";
import { Typography, Box, TextField, InputLabel } from "@mui/material";
import { styled } from "@mui/system";
export const AppContainer = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
flexDirection: 'column',
flexDirection: "column",
width: "100vw",
background: "rgba(39, 40, 44, 1)",
height: "100vh",
radius: "15px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
overflow: 'hidden'
}));
export const AuthenticatedContainer = styled(Box)(({ theme }) => ({
display: "flex",
width: "100%",
height: "100%",
justifyContent: "space-between"
justifyContent: "space-between",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AuthenticatedContainerInnerLeft = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
flexDirection: 'column',
flexDirection: "column",
height: "100%",
width: "100%"
width: "100%",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AuthenticatedContainerInnerRight = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
flexDirection: 'column',
flexDirection: "column",
width: "60px",
height: "100%",
background: "rgba(0, 0, 0, 0.1)"
background: "rgba(0, 0, 0, 0.1)",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
@ -48,105 +51,129 @@ export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({
width: "100%px",
height: "60px",
background: "rgba(0, 0, 0, 0.1)",
padding: '20px'
padding: "20px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const TextP = styled(Typography)(({ theme }) => ({
fontSize: "13px",
fontWeight: 600,
fontFamily: "Inter",
color: "white"
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const TextItalic = styled("span")(({ theme }) => ({
fontSize: "13px",
fontWeight: 600,
fontFamily: "Inter",
color: "white",
fontStyle: "italic"
fontStyle: "italic",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const TextSpan = styled("span")(({ theme }) => ({
fontSize: "13px",
fontFamily: "Inter",
fontWeight: 800,
color: "white"
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AddressBox = styled(Box)`
display: flex;
border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5));
justify-content: space-between;
align-items: center;
width: auto;
height: 25px;
padding: 5px 15px 5px 15px;
gap: 5px;
border-radius: 100px;
font-family: Inter;
font-size: 12px;
font-weight: 600;
line-height: 14.52px;
text-align: left;
color: var(--50-white, rgba(255, 255, 255, 0.5));
cursor: pointer;
transition: all 0.2s;
&:hover {
background-color: rgba(41, 41, 43, 1);
color: white;
svg path {
fill: white; // Fill color changes to white on hover
}
}
export const AddressBox = styled(Box)(({ theme }) => ({
display: "flex",
border: `1px solid ${
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.3)"
}`,
justifyContent: "space-between",
alignItems: "center",
width: "auto",
height: "25px",
padding: "5px 15px",
gap: "5px",
borderRadius: "100px",
fontFamily: "Inter",
fontSize: "12px",
fontWeight: 600,
lineHeight: "14.52px",
textAlign: "left",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
cursor: "pointer",
transition: "all 0.2s",
`
"&:hover": {
backgroundColor:
theme.palette.mode === "dark"
? "rgba(41, 41, 43, 1)"
: "rgba(240, 240, 240, 1)",
color: theme.palette.mode === "dark" ? "#fff" : "#000",
export const CustomButton = styled(Box)`
"svg path": {
fill: theme.palette.mode === "dark" ? "#fff" : "#000",
},
},
}));
/* Authenticate */
export const CustomButton = styled(Box)(({ theme }) => ({
boxSizing: "border-box",
padding: "15px 20px",
gap: "10px",
box-sizing: border-box;
border: `0.5px solid ${
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.3)"
}`,
filter: "drop-shadow(1px 4px 10.5px rgba(0, 0, 0, 0.3))",
borderRadius: "5px",
padding: 15px 20px;
gap: 10px;
display: "inline-flex",
justifyContent: "center",
alignItems: "center",
width: "fit-content",
minWidth: "160px",
cursor: "pointer",
transition: "all 0.2s",
border: 0.5px solid rgba(255, 255, 255, 0.5);
filter: drop-shadow(1px 4px 10.5px rgba(0, 0, 0, 0.3));
border-radius: 5px;
fontWeight: 600,
fontFamily: "Inter",
textAlign: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
display: inline-flex;
"&:hover": {
backgroundColor:
theme.palette.mode === "dark"
? "rgba(41, 41, 43, 1)"
: "rgba(230, 230, 230, 1)",
color: "#fff",
justify-content: center;
align-items: center;
"svg path": {
fill: "#fff",
},
},
}));
width: fit-content;
transition: all 0.2s;
color: black;
min-width: 160px;
cursor: pointer;
font-weight: 600;
font-family: Inter;
color: white;
text-align: center;
&:hover {
background-color: rgba(41, 41, 43, 1);
color: white;
svg path {
fill: white; // Fill color changes to white on hover
}
}
`;
interface CustomButtonProps {
bgColor?: string;
color?: string;
}
export const CustomButtonAccept = styled(Box)<CustomButtonProps>(
({ bgColor, color }) => ({
({ bgColor, color, theme }) => ({
boxSizing: "border-box",
padding: "15px 20px",
gap: "10px",
border: "0.5px solid rgba(255, 255, 255, 0.5)",
border: `0.5px solid ${
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.3)"
}`,
filter: "drop-shadow(1px 4px 10.5px rgba(0,0,0,0.3))",
borderRadius: 5,
display: "inline-flex",
@ -160,31 +187,31 @@ export const CustomButtonAccept = styled(Box)<CustomButtonProps>(
fontFamily: "Inter",
textAlign: "center",
opacity: 0.7,
// Use the passed-in props or fallback defaults
backgroundColor: bgColor || "transparent",
color: color || "white",
// Color and backgroundColor with fallbacks
backgroundColor: bgColor || (theme.palette.mode === "dark" ? "#1d1d1d" : "#f5f5f5"),
color: color || (theme.palette.mode === "dark" ? "#fff" : "#000"),
"&:hover": {
opacity: 1,
backgroundColor: bgColor
? bgColor
: "rgba(41, 41, 43, 1)", // fallback hover bg
color: color || "white",
backgroundColor: bgColor || (theme.palette.mode === "dark" ? "rgba(41, 41, 43, 1)" : "rgba(230, 230, 230, 1)"),
color: color || "#fff",
svg: {
path: {
fill: color || "white",
fill: color || "#fff",
},
},
},
})
);
export const CustomInput = styled(TextField)({
export const CustomInput = styled(TextField)(({ theme }) => ({
width: "183px", // Adjust the width as needed
borderRadius: "5px",
// backgroundColor: "rgba(30, 30, 32, 1)",
outline: "none",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
input: {
fontSize: 10,
fontFamily: "Inter",
@ -199,13 +226,13 @@ export const CustomInput = styled(TextField)({
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
border: "0.5px solid rgba(255, 255, 255, 0.5)",
},
"&:hover fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
border: "0.5px solid rgba(255, 255, 255, 0.5)",
},
"&.Mui-focused fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
border: "0.5px solid rgba(255, 255, 255, 0.5)",
},
},
"& .MuiInput-underline:before": {
@ -217,13 +244,15 @@ export const CustomInput = styled(TextField)({
"& .MuiInput-underline:after": {
borderBottom: "none",
},
});
}));
export const CustomLabel = styled(InputLabel)`
font-weight: 400;
font-family: Inter;
font-size: 10px;
line-height: 12px;
color: rgba(255, 255, 255, 0.5);
`
export const CustomLabel = styled(InputLabel)(({ theme }) => ({
fontWeight: 400,
fontFamily: "Inter",
fontSize: "10px",
lineHeight: "12px",
color:
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.5)",
}));

View File

View File

@ -6,7 +6,6 @@ import {
useRef,
useState,
} from "react";
import "./App.css";
import { useDropzone } from "react-dropzone";
import {
Box,
@ -3562,4 +3561,4 @@ function App() {
);
}
export default App;
export default App;

View File

@ -1008,4 +1008,4 @@ export const NotAuthenticated = ({
</ButtonBase>
</>
);
};
};

View File

@ -1,6 +1,8 @@
import React from "react";
import { useTheme } from "@mui/material";
export const AppsIcon = ({ height = 31, width = 31 }) => {
const theme = useTheme();
export const AppsIcon = ({ color, height = 31, width = 31 }) => {
return (
<svg
width={width}
@ -11,39 +13,39 @@ export const AppsIcon = ({ color, height = 31, width = 31 }) => {
>
<path
d="M3.76596 7.53192C5.84584 7.53192 7.53192 5.84584 7.53192 3.76596C7.53192 1.68608 5.84584 0 3.76596 0C1.68608 0 0 1.68608 0 3.76596C0 5.84584 1.68608 7.53192 3.76596 7.53192Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M15 7.53192C17.0799 7.53192 18.766 5.84584 18.766 3.76596C18.766 1.68608 17.0799 0 15 0C12.9201 0 11.2341 1.68608 11.2341 3.76596C11.2341 5.84584 12.9201 7.53192 15 7.53192Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M26.234 7.53192C28.3139 7.53192 30 5.84584 30 3.76596C30 1.68608 28.3139 0 26.234 0C24.1542 0 22.4681 1.68608 22.4681 3.76596C22.4681 5.84584 24.1542 7.53192 26.234 7.53192Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M3.76596 30.0001C5.84584 30.0001 7.53192 28.314 7.53192 26.2341C7.53192 24.1542 5.84584 22.4681 3.76596 22.4681C1.68608 22.4681 0 24.1542 0 26.2341C0 28.314 1.68608 30.0001 3.76596 30.0001Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M15 30.0002C17.0799 30.0002 18.766 28.3141 18.766 26.2342C18.766 24.1543 17.0799 22.4683 15 22.4683C12.9201 22.4683 11.2341 24.1543 11.2341 26.2342C11.2341 28.3141 12.9201 30.0002 15 30.0002Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M26.234 30.0002C28.3139 30.0002 30 28.3141 30 26.2342C30 24.1543 28.3139 22.4683 26.234 22.4683C24.1542 22.4683 22.4681 24.1543 22.4681 26.2342C22.4681 28.3141 24.1542 30.0002 26.234 30.0002Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M3.76596 18.766C5.84584 18.766 7.53192 17.08 7.53192 15.0001C7.53192 12.9202 5.84584 11.2341 3.76596 11.2341C1.68608 11.2341 0 12.9202 0 15.0001C0 17.08 1.68608 18.766 3.76596 18.766Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M15 18.766C17.0799 18.766 18.766 17.08 18.766 15.0001C18.766 12.9202 17.0799 11.2341 15 11.2341C12.9201 11.2341 11.2341 12.9202 11.2341 15.0001C11.2341 17.08 12.9201 18.766 15 18.766Z"
fill={color}
fill={theme.palette.text.primary}
/>
<path
d="M26.234 18.766C28.3139 18.766 30 17.08 30 15.0001C30 12.9202 28.3139 11.2341 26.234 11.2341C24.1542 11.2341 22.4681 12.9202 22.4681 15.0001C22.4681 17.08 24.1542 18.766 26.234 18.766Z"
fill={color}
fill={theme.palette.text.primary}
/>
</svg>
);

View File

@ -1,12 +1,20 @@
import React from 'react';
import { useTheme } from "@mui/material";
export const HomeIcon= ({ color, height = 20, width = 23 }) => {
return (
<svg width={width} height={height} viewBox="0 0 23 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.936 11.9842C22.8122 12.2972 22.5127 12.502 22.1801 12.5008H19.7155V19.1668C19.714 19.6263 19.3471 19.9985 18.8939 20H14.7862V14.1673C14.7862 12.3265 13.3149 10.8343 11.5 10.8343C9.68509 10.8343 8.21381 12.3265 8.21381 14.1673V20H4.10607C3.65294 19.9985 3.28596 19.6263 3.28452 19.1668V12.5008H0.819874C0.487346 12.502 0.187777 12.2972 0.0640491 11.9842C-0.0642812 11.6739 0.00375033 11.3157 0.236574 11.076L10.9167 0.243778C11.2395 -0.0812593 11.7605 -0.0812593 12.0833 0.243778L22.7634 11.076C22.9963 11.3157 23.0643 11.6739 22.936 11.9842Z" fill={color}/>
</svg>
export const HomeIcon = ({ height = 20, width = 23 }) => {
const theme = useTheme();
);
};
return (
<svg
width={width}
height={height}
viewBox="0 0 23 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22.936 11.9842C22.8122 12.2972 22.5127 12.502 22.1801 12.5008H19.7155V19.1668C19.714 19.6263 19.3471 19.9985 18.8939 20H14.7862V14.1673C14.7862 12.3265 13.3149 10.8343 11.5 10.8343C9.68509 10.8343 8.21381 12.3265 8.21381 14.1673V20H4.10607C3.65294 19.9985 3.28596 19.6263 3.28452 19.1668V12.5008H0.819874C0.487346 12.502 0.187777 12.2972 0.0640491 11.9842C-0.0642812 11.6739 0.00375033 11.3157 0.236574 11.076L10.9167 0.243778C11.2395 -0.0812593 11.7605 -0.0812593 12.0833 0.243778L22.7634 11.076C22.9963 11.3157 23.0643 11.6739 22.936 11.9842Z"
fill={theme.palette.text.primary}
/>
</svg>
);
};

View File

@ -3,7 +3,7 @@ import React from 'react';
export const LogoutIcon= ({ color, height = 20, width = 18}) => {
return (
<svg width={width} height={height} viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.4351 0H1.63891C0.733765 0 0 0.727797 0 1.62558V18.3744C0 19.2722 0.733765 20 1.63891 20H10.4351C11.3403 20 12.0741 19.2722 12.0741 18.3744V12.6013H7.38321C6.54312 12.6013 5.85964 11.9039 5.85964 11.0467V8.87329C5.85964 8.01613 6.54312 7.31875 7.38323 7.31875H12.0741V1.62558C12.0741 0.727797 11.3403 0 10.4351 0ZM6.83334 11.0467C6.83334 11.3719 7.07952 11.6354 7.38321 11.6354H13.1856C13.2548 11.6354 13.3109 11.6955 13.3109 11.7696V12.8632C13.3109 13.3492 13.8299 13.6259 14.1922 13.3329L17.7816 10.4298C18.0728 10.1942 18.0728 9.72579 17.7816 9.49024L14.1922 6.58709C13.8299 6.29409 13.3109 6.57077 13.3109 7.05684V8.1504C13.3109 8.2245 13.2548 8.28454 13.1856 8.28454H7.38322C7.07952 8.28454 6.83334 8.54813 6.83334 8.87329V11.0467Z" fill={color} />
<path fillRule="evenodd" clipRule="evenodd" d="M10.4351 0H1.63891C0.733765 0 0 0.727797 0 1.62558V18.3744C0 19.2722 0.733765 20 1.63891 20H10.4351C11.3403 20 12.0741 19.2722 12.0741 18.3744V12.6013H7.38321C6.54312 12.6013 5.85964 11.9039 5.85964 11.0467V8.87329C5.85964 8.01613 6.54312 7.31875 7.38323 7.31875H12.0741V1.62558C12.0741 0.727797 11.3403 0 10.4351 0ZM6.83334 11.0467C6.83334 11.3719 7.07952 11.6354 7.38321 11.6354H13.1856C13.2548 11.6354 13.3109 11.6955 13.3109 11.7696V12.8632C13.3109 13.3492 13.8299 13.6259 14.1922 13.3329L17.7816 10.4298C18.0728 10.1942 18.0728 9.72579 17.7816 9.49024L14.1922 6.58709C13.8299 6.29409 13.3109 6.57077 13.3109 7.05684V8.1504C13.3109 8.2245 13.2548 8.28454 13.1856 8.28454H7.38322C7.07952 8.28454 6.83334 8.54813 6.83334 8.87329V11.0467Z" fill={color} />
</svg>

View File

@ -1,13 +1,30 @@
import React from 'react';
import { useTheme } from "@mui/material";
export const MessagingIcon= ({ color, height = 31, width = 31 }) => {
return (
<svg width={width} height={height} viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.3937 4.49877C23.6712 1.56681 3.1922 8.74911 3.20912 11.3714C3.22829 14.345 11.2067 15.2597 13.4181 15.8802C14.748 16.2532 15.1041 16.6357 15.4107 18.0302C16.7995 24.3457 17.4967 27.487 19.0859 27.5571C21.6189 27.6691 29.0507 7.36011 26.3937 4.49877Z" stroke={color} stroke-width="2"/>
<path d="M14.4591 16.3076L18.8341 11.9326" stroke={color} stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
export const MessagingIcon = ({ color, height = 31, width = 31 }) => {
const theme = useTheme();
);
};
const setColor = color ? color : theme.palette.text.primary
return (
<svg
width={width}
height={height}
viewBox="0 0 31 31"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M26.3937 4.49877C23.6712 1.56681 3.1922 8.74911 3.20912 11.3714C3.22829 14.345 11.2067 15.2597 13.4181 15.8802C14.748 16.2532 15.1041 16.6357 15.4107 18.0302C16.7995 24.3457 17.4967 27.487 19.0859 27.5571C21.6189 27.6691 29.0507 7.36011 26.3937 4.49877Z"
stroke={setColor}
strokeWidth="2"
/>
<path
d="M14.4591 16.3076L18.8341 11.9326"
stroke={setColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};

View File

@ -3,7 +3,7 @@ import React from 'react';
export const MessagingIcon2= ({ color = '#8F8F91', height = 24, width =24 }) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.6636 0.00168233C22.6127 -0.000756257 22.5614 -0.000627677 22.5099 0.00261984C22.3724 0.0112798 22.2331 0.0405753 22.0969 0.093558L1.02096 8.28971C0.362343 8.54585 -0.00366118 9.18408 2.76147e-05 9.79253C0.00371641 10.401 0.377567 11.0341 1.03925 11.2822L9.02065 14.2752C9.34631 14.3974 9.60258 14.6536 9.72471 14.9793L12.7177 22.9607C12.9658 23.6224 13.5989 23.9963 14.2074 24C14.8158 24.0037 15.454 23.6376 15.7102 22.979L23.9063 1.90295C24.1182 1.35797 23.9526 0.768987 23.5917 0.408091C23.3549 0.171254 23.02 0.0187526 22.6636 0.00168233ZM18.4022 4.99812C18.5613 4.99815 18.7139 5.06138 18.8264 5.17391C18.9389 5.28643 19.0021 5.43902 19.0021 5.59813C19.0021 5.75724 18.9389 5.90983 18.8264 6.02235L13.2239 11.6244C13.1114 11.7369 12.9588 11.8001 12.7997 11.8001C12.6406 11.8001 12.488 11.7369 12.3755 11.6244C12.263 11.5119 12.1998 11.3593 12.1998 11.2002C12.1998 11.0411 12.263 10.8885 12.3755 10.776L17.9775 5.17391C18.0333 5.11813 18.0995 5.0739 18.1724 5.04374C18.2452 5.01357 18.3233 4.99807 18.4022 4.99812Z" fill={color}/>
<path fillRule="evenodd" clipRule="evenodd" d="M22.6636 0.00168233C22.6127 -0.000756257 22.5614 -0.000627677 22.5099 0.00261984C22.3724 0.0112798 22.2331 0.0405753 22.0969 0.093558L1.02096 8.28971C0.362343 8.54585 -0.00366118 9.18408 2.76147e-05 9.79253C0.00371641 10.401 0.377567 11.0341 1.03925 11.2822L9.02065 14.2752C9.34631 14.3974 9.60258 14.6536 9.72471 14.9793L12.7177 22.9607C12.9658 23.6224 13.5989 23.9963 14.2074 24C14.8158 24.0037 15.454 23.6376 15.7102 22.979L23.9063 1.90295C24.1182 1.35797 23.9526 0.768987 23.5917 0.408091C23.3549 0.171254 23.02 0.0187526 22.6636 0.00168233ZM18.4022 4.99812C18.5613 4.99815 18.7139 5.06138 18.8264 5.17391C18.9389 5.28643 19.0021 5.43902 19.0021 5.59813C19.0021 5.75724 18.9389 5.90983 18.8264 6.02235L13.2239 11.6244C13.1114 11.7369 12.9588 11.8001 12.7997 11.8001C12.6406 11.8001 12.488 11.7369 12.3755 11.6244C12.263 11.5119 12.1998 11.3593 12.1998 11.2002C12.1998 11.0411 12.263 10.8885 12.3755 10.776L17.9775 5.17391C18.0333 5.11813 18.0995 5.0739 18.1724 5.04374C18.2452 5.01357 18.3233 4.99807 18.4022 4.99812Z" fill={color}/>
</svg>

View File

@ -3,7 +3,7 @@ import React from 'react';
export const NotificationIcon2= ({ color = 'white', height = 15, width = 15 }) => {
return (
<svg width={width} height={height} viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.50253 0.80505C8.50253 0.360285 8.14231 0 7.69818 0C7.25348 0 6.89325 0.36027 6.89325 0.80505V1.6142C6.89325 2.05896 7.25346 2.41866 7.69818 2.41866C8.14229 2.41866 8.50253 2.05839 8.50253 1.61361V0.80505ZM7.06691 3.12343C7.45178 2.90163 7.944 3.03366 8.16577 3.41857L12.3049 10.5872C12.5231 10.9715 12.3905 11.4603 12.0074 11.6815C11.6243 11.9027 11.1344 11.773 10.9109 11.3916L10.8517 11.2884L7.53454 12.0588C7.73401 12.7922 7.56388 13.5767 7.07751 14.1606C6.59173 14.7444 5.85192 15.0548 5.09454 14.992C4.33771 14.9286 3.65892 14.5009 3.27588 13.8443L3.27353 13.8414L2.86989 13.1431L1.30986 13.5046L1.31045 13.504C1.08047 13.5574 0.842856 13.4547 0.724941 13.2499L0.0713702 12.118C-0.0459665 11.9138 -0.0166327 11.6562 0.144705 11.4837L6.83346 4.32684L6.77245 4.22298C6.66567 4.03814 6.63633 3.8187 6.69207 3.61216C6.74722 3.40561 6.8821 3.23022 7.06691 3.12343ZM4.50841 12.7617L5.96397 12.4237C6.09539 12.7746 5.9364 13.1683 5.59729 13.3279C5.25819 13.4875 4.85338 13.3602 4.66623 13.0351L4.50841 12.7617ZM15 7.30235C15 7.51593 14.9155 7.72072 14.7647 7.87152C14.614 8.02232 14.4092 8.1074 14.1957 8.1074H13.3866C12.9419 8.1074 12.5823 7.74713 12.5823 7.30235C12.5823 6.85817 12.9425 6.49788 13.3872 6.49788H14.1951C14.6398 6.49788 15 6.85815 15 7.30235ZM2.01088 8.10681C2.45558 8.10681 2.81582 7.74713 2.81582 7.30235C2.81582 6.85817 2.4556 6.49788 2.01088 6.49788H1.20185C0.757149 6.49788 0.397502 6.85815 0.397502 7.30235C0.397502 7.74711 0.75772 8.1074 1.20244 8.1074H2.01147L2.01088 8.10681ZM4.35176 3.95659C4.03789 4.2705 3.52864 4.27109 3.21477 3.95717L2.53481 3.27712C2.37465 3.12808 2.28253 2.92036 2.27843 2.70209C2.27491 2.48381 2.35998 2.27374 2.51428 2.11884C2.66857 1.96453 2.8792 1.87943 3.09744 1.88355C3.31568 1.88766 3.52278 1.97978 3.6718 2.13937L4.35295 2.81826C4.50431 2.96906 4.58879 3.17443 4.58879 3.38802C4.58879 3.60161 4.50431 3.80639 4.35295 3.95719L4.35176 3.95659ZM12.861 3.27653L12.8616 3.27712C13.1567 2.95967 13.1479 2.46562 12.8416 2.15932C12.5354 1.85302 12.0414 1.84422 11.724 2.13937L11.0352 2.82589C10.7214 3.1398 10.7214 3.6503 11.0352 3.9648C11.3497 4.27872 11.8595 4.27872 12.1734 3.9648L12.861 3.27829V3.27653Z" fill={color}/>
<path fillRule="evenodd" clipRule="evenodd" d="M8.50253 0.80505C8.50253 0.360285 8.14231 0 7.69818 0C7.25348 0 6.89325 0.36027 6.89325 0.80505V1.6142C6.89325 2.05896 7.25346 2.41866 7.69818 2.41866C8.14229 2.41866 8.50253 2.05839 8.50253 1.61361V0.80505ZM7.06691 3.12343C7.45178 2.90163 7.944 3.03366 8.16577 3.41857L12.3049 10.5872C12.5231 10.9715 12.3905 11.4603 12.0074 11.6815C11.6243 11.9027 11.1344 11.773 10.9109 11.3916L10.8517 11.2884L7.53454 12.0588C7.73401 12.7922 7.56388 13.5767 7.07751 14.1606C6.59173 14.7444 5.85192 15.0548 5.09454 14.992C4.33771 14.9286 3.65892 14.5009 3.27588 13.8443L3.27353 13.8414L2.86989 13.1431L1.30986 13.5046L1.31045 13.504C1.08047 13.5574 0.842856 13.4547 0.724941 13.2499L0.0713702 12.118C-0.0459665 11.9138 -0.0166327 11.6562 0.144705 11.4837L6.83346 4.32684L6.77245 4.22298C6.66567 4.03814 6.63633 3.8187 6.69207 3.61216C6.74722 3.40561 6.8821 3.23022 7.06691 3.12343ZM4.50841 12.7617L5.96397 12.4237C6.09539 12.7746 5.9364 13.1683 5.59729 13.3279C5.25819 13.4875 4.85338 13.3602 4.66623 13.0351L4.50841 12.7617ZM15 7.30235C15 7.51593 14.9155 7.72072 14.7647 7.87152C14.614 8.02232 14.4092 8.1074 14.1957 8.1074H13.3866C12.9419 8.1074 12.5823 7.74713 12.5823 7.30235C12.5823 6.85817 12.9425 6.49788 13.3872 6.49788H14.1951C14.6398 6.49788 15 6.85815 15 7.30235ZM2.01088 8.10681C2.45558 8.10681 2.81582 7.74713 2.81582 7.30235C2.81582 6.85817 2.4556 6.49788 2.01088 6.49788H1.20185C0.757149 6.49788 0.397502 6.85815 0.397502 7.30235C0.397502 7.74711 0.75772 8.1074 1.20244 8.1074H2.01147L2.01088 8.10681ZM4.35176 3.95659C4.03789 4.2705 3.52864 4.27109 3.21477 3.95717L2.53481 3.27712C2.37465 3.12808 2.28253 2.92036 2.27843 2.70209C2.27491 2.48381 2.35998 2.27374 2.51428 2.11884C2.66857 1.96453 2.8792 1.87943 3.09744 1.88355C3.31568 1.88766 3.52278 1.97978 3.6718 2.13937L4.35295 2.81826C4.50431 2.96906 4.58879 3.17443 4.58879 3.38802C4.58879 3.60161 4.50431 3.80639 4.35295 3.95719L4.35176 3.95659ZM12.861 3.27653L12.8616 3.27712C13.1567 2.95967 13.1479 2.46562 12.8416 2.15932C12.5354 1.85302 12.0414 1.84422 11.724 2.13937L11.0352 2.82589C10.7214 3.1398 10.7214 3.6503 11.0352 3.9648C11.3497 4.27872 11.8595 4.27872 12.1734 3.9648L12.861 3.27829V3.27653Z" fill={color}/>
</svg>
);

View File

@ -3,7 +3,7 @@ import React from 'react';
export const ThreadsIcon= ({ color = 'white', height = 11, width = 15 }) => {
return (
<svg width={width} height={height} viewBox="0 0 15 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.76526 1.80943H6.51017C5.91236 1.80943 5.42723 2.37147 5.42723 3.06406V6.55419V6.82615H4L1.90297 9L2.00782 6.82615H0.8482C0.380282 6.82615 0 6.38558 0 5.84347V0.982675C0 0.440572 0.380282 0 0.8482 0H7.1518C7.62128 0 8 0.440572 8 0.982675V1.80943H7.76526ZM8.89437 2H14.0458C14.5722 2 15 2.44057 15 2.98268V7.84166C15 8.38558 14.5722 8.82434 14.0458 8.82434H12.7412L12.8592 11L10.5 8.82434H6.95423C6.42606 8.82434 6 8.38558 6 7.84166V7.01672V6.74476V6.47281V2.98268C6 2.44057 6.42606 2 6.95423 2H8.3662H8.63028H8.89437Z" fill={color}/>
<path fillRule="evenodd" clipRule="evenodd" d="M7.76526 1.80943H6.51017C5.91236 1.80943 5.42723 2.37147 5.42723 3.06406V6.55419V6.82615H4L1.90297 9L2.00782 6.82615H0.8482C0.380282 6.82615 0 6.38558 0 5.84347V0.982675C0 0.440572 0.380282 0 0.8482 0H7.1518C7.62128 0 8 0.440572 8 0.982675V1.80943H7.76526ZM8.89437 2H14.0458C14.5722 2 15 2.44057 15 2.98268V7.84166C15 8.38558 14.5722 8.82434 14.0458 8.82434H12.7412L12.8592 11L10.5 8.82434H6.95423C6.42606 8.82434 6 8.38558 6 7.84166V7.01672V6.74476V6.47281V2.98268C6 2.44057 6.42606 2 6.95423 2H8.3662H8.63028H8.89437Z" fill={color}/>
</svg>

View File

@ -1,12 +1,26 @@
import React from 'react';
import React from "react";
export const WalletIcon= ({ color, height, width }) => {
return (
<svg width={width || 30} height={width || 30} viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.0118 22.0891C18.0124 22.8671 16.6997 23.3391 15.2618 23.3391C13.8241 23.3391 12.5113 22.8671 11.5118 22.0891" stroke={color} stroke-width="2" stroke-linecap="round"/>
<path d="M3.20108 17.356C2.7598 14.4844 2.53917 13.0486 3.08205 11.7758C3.62493 10.503 4.82938 9.63215 7.23827 7.89044L9.03808 6.58911C12.0347 4.42245 13.5331 3.33911 15.2618 3.33911C16.9907 3.33911 18.4889 4.42245 21.4856 6.58911L23.2854 7.89044C25.6943 9.63215 26.8988 10.503 27.4417 11.7758C27.9846 13.0486 27.7639 14.4844 27.3226 17.356L26.9463 19.8046C26.3208 23.8752 26.0079 25.9106 24.5481 27.1249C23.0882 28.3391 20.9539 28.3391 16.6853 28.3391H13.8383C9.56977 28.3391 7.43548 28.3391 5.97559 27.1249C4.5157 25.9106 4.20293 23.8752 3.57738 19.8046L3.20108 17.356Z" stroke={color} stroke-width="2" stroke-linejoin="round"/>
</svg>
);
};
export const WalletIcon = ({ color, height, width }) => {
return (
<svg
width={width || 30}
height={width || 30}
viewBox="0 0 31 31"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.0118 22.0891C18.0124 22.8671 16.6997 23.3391 15.2618 23.3391C13.8241 23.3391 12.5113 22.8671 11.5118 22.0891"
stroke={color}
strokeWidth="2"
strokeLinecap="round"
/>
<path
d="M3.20108 17.356C2.7598 14.4844 2.53917 13.0486 3.08205 11.7758C3.62493 10.503 4.82938 9.63215 7.23827 7.89044L9.03808 6.58911C12.0347 4.42245 13.5331 3.33911 15.2618 3.33911C16.9907 3.33911 18.4889 4.42245 21.4856 6.58911L23.2854 7.89044C25.6943 9.63215 26.8988 10.503 27.4417 11.7758C27.9846 13.0486 27.7639 14.4844 27.3226 17.356L26.9463 19.8046C26.3208 23.8752 26.0079 25.9106 24.5481 27.1249C23.0882 28.3391 20.9539 28.3391 16.6853 28.3391H13.8383C9.56977 28.3391 7.43548 28.3391 5.97559 27.1249C4.5157 25.9106 4.20293 23.8752 3.57738 19.8046L3.20108 17.356Z"
stroke={color}
strokeWidth="2"
strokeLinejoin="round"
/>
</svg>
);
};

View File

@ -1,20 +1,27 @@
import React from 'react';
import { styled } from '@mui/system';
import { SVGProps } from './interfaces';
import React from "react";
import { styled } from "@mui/system";
import { SVGProps } from "./interfaces";
// Create a styled container with hover effects
const SvgContainer = styled('svg')({
'& path': {
fill: 'rgba(41, 41, 43, 1)', // Default to red if no color prop
}
const SvgContainer = styled("svg")({
"& path": {
fill: "rgba(41, 41, 43, 1)", // Default to red if no color prop
},
});
export const CreateThreadIcon:React.FC<SVGProps> = ({ color, opacity }) => {
export const CreateThreadIcon: React.FC<SVGProps> = ({ color, opacity }) => {
return (
<SvgContainer width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 9.80209V9.0205C0.0460138 8.67679 0.080024 8.31425 0.144043 7.98466C0.469856 6.30568 1.25577 4.79934 2.38071 3.6977C4.13924 1.88262 6.22987 0.985679 8.52256 0.674927C9.9086 0.485649 11.3116 0.565177 12.6758 0.910345C14.5124 1.34351 16.1889 2.2075 17.6053 3.67886C18.7276 4.84183 19.5319 6.24257 19.858 7.98466C19.918 8.31189 19.952 8.64383 20 8.97577V9.80209C19.9827 9.8676 19.9693 9.93447 19.96 10.0022C19.8708 11.2186 19.5113 12.3861 18.9177 13.3875C17.961 15.0025 16.6297 16.2594 15.0825 17.0082C12.4657 18.3525 9.75693 18.5667 6.98209 17.8346C6.8589 17.8074 6.73157 17.8264 6.61799 17.8887C5.15955 18.7339 3.70511 19.5908 2.24867 20.4501C2.18866 20.4854 2.12464 20.5183 2.0146 20.5748L3.78714 16.3703C3.37301 16.0148 2.96889 15.7017 2.60078 15.3415C1.42243 14.1879 0.556167 12.7895 0.182055 11.0192C0.0980294 10.6213 0.060018 10.2094 0 9.80209ZM14.0042 10.5931C14.1362 10.5968 14.2676 10.5698 14.3907 10.5135C14.5138 10.4572 14.6262 10.3728 14.7214 10.2651C14.8167 10.1574 14.8928 10.0286 14.9455 9.8861C14.9982 9.7436 15.0264 9.59023 15.0285 9.43484V9.4113C15.0285 9.25517 15.0024 9.10058 14.9516 8.95634C14.9008 8.8121 14.8264 8.68104 14.7326 8.57064C14.6388 8.46025 14.5274 8.37268 14.4048 8.31293C14.2823 8.25319 14.1509 8.22243 14.0182 8.22243C13.8855 8.22243 13.7542 8.25319 13.6316 8.31293C13.509 8.37268 13.3976 8.46025 13.3038 8.57064C13.21 8.68104 13.1356 8.8121 13.0848 8.95634C13.034 9.10058 13.0079 9.25517 13.0079 9.4113C13.0074 9.56588 13.0327 9.71906 13.0825 9.86211C13.1323 10.0052 13.2055 10.1353 13.2981 10.245C13.3906 10.3547 13.5005 10.442 13.6217 10.5017C13.7429 10.5614 13.8728 10.5925 14.0042 10.5931ZM10.003 10.5931C10.203 10.5926 10.3983 10.5225 10.5644 10.3915C10.7306 10.2606 10.86 10.0746 10.9364 9.85719C11.0129 9.63976 11.0329 9.40056 10.9939 9.16977C10.9549 8.93898 10.8588 8.72694 10.7175 8.5604C10.5763 8.39385 10.3962 8.28026 10.2002 8.23396C10.0041 8.18765 9.80084 8.21071 9.61591 8.30022C9.43099 8.38973 9.27273 8.54168 9.1611 8.7369C9.04948 8.93212 8.98949 9.16187 8.9887 9.39717C8.98975 9.71356 9.09688 10.0167 9.28682 10.2406C9.47675 10.4646 9.73413 10.5912 10.003 10.5931ZM4.98349 9.3854C4.9836 9.61979 5.04316 9.8488 5.15456 10.0431C5.26595 10.2374 5.42411 10.3882 5.60876 10.476C5.79341 10.5639 5.99616 10.5849 6.19102 10.5364C6.38588 10.4878 6.56399 10.3719 6.70252 10.2035C6.84105 10.0351 6.93371 9.82183 6.96861 9.59108C7.00352 9.36032 6.97909 9.12255 6.89845 8.90823C6.8178 8.69392 6.68463 8.51281 6.51597 8.38811C6.34732 8.26342 6.15087 8.20081 5.95179 8.20831C5.69208 8.21809 5.44579 8.34641 5.26507 8.56611C5.08434 8.78581 4.98336 9.07963 4.98349 9.3854Z" fill="#29292B"/>
<SvgContainer
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 9.80209V9.0205C0.0460138 8.67679 0.080024 8.31425 0.144043 7.98466C0.469856 6.30568 1.25577 4.79934 2.38071 3.6977C4.13924 1.88262 6.22987 0.985679 8.52256 0.674927C9.9086 0.485649 11.3116 0.565177 12.6758 0.910345C14.5124 1.34351 16.1889 2.2075 17.6053 3.67886C18.7276 4.84183 19.5319 6.24257 19.858 7.98466C19.918 8.31189 19.952 8.64383 20 8.97577V9.80209C19.9827 9.8676 19.9693 9.93447 19.96 10.0022C19.8708 11.2186 19.5113 12.3861 18.9177 13.3875C17.961 15.0025 16.6297 16.2594 15.0825 17.0082C12.4657 18.3525 9.75693 18.5667 6.98209 17.8346C6.8589 17.8074 6.73157 17.8264 6.61799 17.8887C5.15955 18.7339 3.70511 19.5908 2.24867 20.4501C2.18866 20.4854 2.12464 20.5183 2.0146 20.5748L3.78714 16.3703C3.37301 16.0148 2.96889 15.7017 2.60078 15.3415C1.42243 14.1879 0.556167 12.7895 0.182055 11.0192C0.0980294 10.6213 0.060018 10.2094 0 9.80209ZM14.0042 10.5931C14.1362 10.5968 14.2676 10.5698 14.3907 10.5135C14.5138 10.4572 14.6262 10.3728 14.7214 10.2651C14.8167 10.1574 14.8928 10.0286 14.9455 9.8861C14.9982 9.7436 15.0264 9.59023 15.0285 9.43484V9.4113C15.0285 9.25517 15.0024 9.10058 14.9516 8.95634C14.9008 8.8121 14.8264 8.68104 14.7326 8.57064C14.6388 8.46025 14.5274 8.37268 14.4048 8.31293C14.2823 8.25319 14.1509 8.22243 14.0182 8.22243C13.8855 8.22243 13.7542 8.25319 13.6316 8.31293C13.509 8.37268 13.3976 8.46025 13.3038 8.57064C13.21 8.68104 13.1356 8.8121 13.0848 8.95634C13.034 9.10058 13.0079 9.25517 13.0079 9.4113C13.0074 9.56588 13.0327 9.71906 13.0825 9.86211C13.1323 10.0052 13.2055 10.1353 13.2981 10.245C13.3906 10.3547 13.5005 10.442 13.6217 10.5017C13.7429 10.5614 13.8728 10.5925 14.0042 10.5931ZM10.003 10.5931C10.203 10.5926 10.3983 10.5225 10.5644 10.3915C10.7306 10.2606 10.86 10.0746 10.9364 9.85719C11.0129 9.63976 11.0329 9.40056 10.9939 9.16977C10.9549 8.93898 10.8588 8.72694 10.7175 8.5604C10.5763 8.39385 10.3962 8.28026 10.2002 8.23396C10.0041 8.18765 9.80084 8.21071 9.61591 8.30022C9.43099 8.38973 9.27273 8.54168 9.1611 8.7369C9.04948 8.93212 8.98949 9.16187 8.9887 9.39717C8.98975 9.71356 9.09688 10.0167 9.28682 10.2406C9.47675 10.4646 9.73413 10.5912 10.003 10.5931ZM4.98349 9.3854C4.9836 9.61979 5.04316 9.8488 5.15456 10.0431C5.26595 10.2374 5.42411 10.3882 5.60876 10.476C5.79341 10.5639 5.99616 10.5849 6.19102 10.5364C6.38588 10.4878 6.56399 10.3719 6.70252 10.2035C6.84105 10.0351 6.93371 9.82183 6.96861 9.59108C7.00352 9.36032 6.97909 9.12255 6.89845 8.90823C6.8178 8.69392 6.68463 8.51281 6.51597 8.38811C6.34732 8.26342 6.15087 8.20081 5.95179 8.20831C5.69208 8.21809 5.44579 8.34641 5.26507 8.56611C5.08434 8.78581 4.98336 9.07963 4.98349 9.3854Z"
fill="#29292B"
/>
</SvgContainer>
);
};

View File

@ -1,10 +1,24 @@
import React from 'react'
import { useTheme } from "@mui/material";
export const SaveIcon = ({ color }) => {
const theme = useTheme();
const setColor = color ? color : theme.palette.text.primary
export const SaveIcon = ({color = '#8F8F91'}) => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.18182 0C0.976833 0 0 0.976833 0 2.18182V21.8182C0 23.0232 0.976833 24 2.18182 24H21.8182C23.0232 24 24 23.0232 24 21.8182V7.4492C24 6.87053 23.7701 6.31559 23.3609 5.90641L18.0936 0.639044C17.6844 0.229866 17.1295 0 16.5508 0H16.3636C15.7611 0 15.2727 0.488422 15.2727 1.09091V5.45455C15.2727 6.65953 14.2959 7.63636 13.0909 7.63636H6.54545C5.34047 7.63636 4.36364 6.65953 4.36364 5.45455V1.09091C4.36364 0.488422 3.87521 0 3.27273 0H2.18182ZM12 18.5455C13.8075 18.5455 15.2727 17.0803 15.2727 15.2727C15.2727 13.4652 13.8075 12 12 12C10.1925 12 8.72727 13.4652 8.72727 15.2727C8.72727 17.0803 10.1925 18.5455 12 18.5455Z" fill={color}/>
</svg>
)
}
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2.18182 0C0.976833 0 0 0.976833 0 2.18182V21.8182C0 23.0232 0.976833 24 2.18182 24H21.8182C23.0232 24 24 23.0232 24 21.8182V7.4492C24 6.87053 23.7701 6.31559 23.3609 5.90641L18.0936 0.639044C17.6844 0.229866 17.1295 0 16.5508 0H16.3636C15.7611 0 15.2727 0.488422 15.2727 1.09091V5.45455C15.2727 6.65953 14.2959 7.63636 13.0909 7.63636H6.54545C5.34047 7.63636 4.36364 6.65953 4.36364 5.45455V1.09091C4.36364 0.488422 3.87521 0 3.27273 0H2.18182ZM12 18.5455C13.8075 18.5455 15.2727 17.0803 15.2727 15.2727C15.2727 13.4652 13.8075 12 12 12C10.1925 12 8.72727 13.4652 8.72727 15.2727C8.72727 17.0803 10.1925 18.5455 12 18.5455Z"
fill={setColor}
/>
</svg>
);
};

View File

@ -12,7 +12,7 @@ const SvgContainer = styled('svg')({
export const SendNewMessage:React.FC<SVGProps> = ({ color, opacity }) => {
return (
<SvgContainer width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.33271 10.2306C2.88006 10.001 2.89088 9.65814 3.3554 9.46527L16.3563 4.06742C16.8214 3.87427 17.0961 4.11004 16.9689 4.59692L14.1253 15.4847C13.9985 15.9703 13.5515 16.1438 13.1241 15.8705L10.0773 13.9219C9.8629 13.7848 9.56272 13.8345 9.40985 14.0292L8.41215 15.2997C8.10197 15.6946 7.71724 15.6311 7.5525 15.1567L6.67584 12.6326C6.51125 12.1587 6.01424 11.5902 5.55821 11.359L3.33271 10.2306Z" />
<path fillRule="evenodd" clipRule="evenodd" d="M3.33271 10.2306C2.88006 10.001 2.89088 9.65814 3.3554 9.46527L16.3563 4.06742C16.8214 3.87427 17.0961 4.11004 16.9689 4.59692L14.1253 15.4847C13.9985 15.9703 13.5515 16.1438 13.1241 15.8705L10.0773 13.9219C9.8629 13.7848 9.56272 13.8345 9.40985 14.0292L8.41215 15.2997C8.10197 15.6946 7.71724 15.6311 7.5525 15.1567L6.67584 12.6326C6.51125 12.1587 6.01424 11.5902 5.55821 11.359L3.33271 10.2306Z" />
</SvgContainer>
);

View File

@ -1,19 +1,27 @@
/* HTML: <div class="loader"></div> */
.loader-bar {
width: 45px;
aspect-ratio: .75;
--c:no-repeat linear-gradient(currentColor 0 0);
background:
var(--c) 0% 100%,
var(--c) 50% 100%,
var(--c) 100% 100%;
background-size: 20% 65%;
animation: l8 1s infinite linear;
width: 45px;
aspect-ratio: 0.75;
--c: no-repeat linear-gradient(currentColor 0 0);
background: var(--c) 0% 100%, var(--c) 50% 100%, var(--c) 100% 100%;
background-size: 20% 65%;
animation: l8 1s infinite linear;
}
@keyframes l8 {
16.67% {
background-position: 0% 0%, 50% 100%, 100% 100%;
}
@keyframes l8 {
16.67% {background-position: 0% 0% ,50% 100%,100% 100%}
33.33% {background-position: 0% 0% ,50% 0% ,100% 100%}
50% {background-position: 0% 0% ,50% 0% ,100% 0% }
66.67% {background-position: 0% 100%,50% 0% ,100% 0% }
83.33% {background-position: 0% 100%,50% 100%,100% 0% }
}
33.33% {
background-position: 0% 0%, 50% 0%, 100% 100%;
}
50% {
background-position: 0% 0%, 50% 0%, 100% 0%;
}
66.67% {
background-position: 0% 100%, 50% 0%, 100% 0%;
}
83.33% {
background-position: 0% 100%, 50% 100%, 100% 0%;
}
}

View File

@ -1,7 +1,6 @@
.lds-ellipsis {
color: white
}
color: white;
}
.lds-ellipsis,
.lds-ellipsis div {
box-sizing: border-box;
@ -61,4 +60,3 @@
transform: translate(24px, 0);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */
}

View File

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

View 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);

View 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;

View File

@ -1,43 +1,40 @@
@font-face {
font-family: 'Inter';
src: url('./styles/fonts/Inter-SemiBold.ttf') format('truetype');
font-family: "Inter";
src: url("./styles/fonts/Inter-SemiBold.ttf") format("truetype");
font-weight: 600;
}
@font-face {
font-family: 'Inter';
src: url('./styles/fonts/Inter-ExtraBold.ttf') format('truetype');
font-family: "Inter";
src: url("./styles/fonts/Inter-ExtraBold.ttf") format("truetype");
font-weight: 800;
}
@font-face {
font-family: 'Inter';
src: url('./styles/fonts/Inter-Bold.ttf') format('truetype');
font-family: "Inter";
src: url("./styles/fonts/Inter-Bold.ttf") format("truetype");
font-weight: 700;
}
@font-face {
font-family: 'Inter';
src: url('./styles/fonts/Inter-Regular.ttf') format('truetype');
font-family: "Inter";
src: url("./styles/fonts/Inter-Regular.ttf") format("truetype");
font-weight: 400;
}
:root {
padding: 0px;
margin: 0px;
box-sizing: border-box !important;
word-break: break-word;
--color-instance : #1E1E20;
--color-instance: #1e1e20;
--color-instance-popover-bg: #222222;
--Mail-Background: rgba(49, 51, 56, 1);
--new-message-text: black;
--bg-primary : rgba(31, 32, 35, 1);
--bg-primary: rgba(31, 32, 35, 1);
--bg-2: #27282c;
--bg-3: rgba(0, 0, 0, 0.1);
--unread: #4297e2;
--danger: #B14646;
--apps-circle: #1F2023;
--green: #5EB049;
--unread: #4297e2;
--danger: #b14646;
--apps-circle: #1f2023;
--green: #5eb049;
}
body {
@ -97,10 +94,8 @@ body {
initial-value: transparent;
}
.scrollable-container {
transition: --var1 0.4s;
}
.scrollable-container:hover {
@ -115,11 +110,6 @@ body {
opacity: 0;
}
/* Mobile-specific scrollbar styles */
@media only screen and (max-width: 600px) {
::-webkit-scrollbar {
@ -137,11 +127,11 @@ body {
background-color: whitesmoke;
}
html, body {
overscroll-behavior:none !important;
html,
body {
overscroll-behavior: none !important;
}
.swiper {
width: 100%;
}

View File

@ -1,81 +1,20 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import "./messaging/messagesToBackground";
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { CssBaseline } from '@mui/material';
import { MessageQueueProvider } from './MessageQueueContext.tsx';
import { RecoilRoot } from 'recoil';
const theme = createTheme({
palette: {
primary: {
main: '#232428', // Primary color (e.g., used for buttons, headers, etc.)
},
secondary: {
main: '#232428', // Secondary color
},
background: {
default: '#27282c', // Default background color
paper: '#1d1d1d', // Paper component background (for dropdowns, dialogs, etc.)
},
text: {
primary: '#ffffff', // White as the primary text color
secondary: '#b0b0b0', // Light gray for secondary text
disabled: '#808080', // Gray for disabled text
},
action: {
// disabledBackground: 'set color of background here',
disabled: 'rgb(255 255 255 / 70%)'
}
},
typography: {
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', // Font family
h1: {
color: '#ffffff', // White color for h1 elements
},
h2: {
color: '#ffffff', // White color for h2 elements
},
body1: {
color: '#ffffff', // Default body text color
},
body2: {
color: '#b0b0b0', // Lighter text for body2, often used for secondary text
},
},
components: {
MuiOutlinedInput: {
styleOverrides: {
root: {
".MuiOutlinedInput-notchedOutline": {
borderColor: "white", // ⚪ Default outline color
},
},
},
},
MuiSelect: {
styleOverrides: {
icon: {
color: "white", // ✅ Caret (dropdown arrow) color
},
},
},
},
});
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import "./messaging/messagesToBackground";
import { MessageQueueProvider } from "./MessageQueueContext.tsx";
import { RecoilRoot } from "recoil";
import { ThemeProvider } from "./components/Theme/ThemeContext.tsx";
export default theme;
ReactDOM.createRoot(document.getElementById('root')!).render(
ReactDOM.createRoot(document.getElementById("root")!).render(
<>
<ThemeProvider theme={theme}>
<CssBaseline />
<MessageQueueProvider>
<RecoilRoot>
<App />
</RecoilRoot>
</MessageQueueProvider>
<ThemeProvider>
<MessageQueueProvider>
<RecoilRoot>
<App />
</RecoilRoot>
</MessageQueueProvider>
</ThemeProvider>
</>,
)
</>
);

View File

@ -4,6 +4,7 @@
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"noImplicitAny": false,
"skipLibCheck": true,
/* Bundler mode */

View File

@ -1,51 +1,55 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// Import path module for resolving file paths
import fixReactVirtualized from 'esbuild-plugin-react-virtualized'
import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
import { VitePWA } from 'vite-plugin-pwa';
import fixReactVirtualized from "esbuild-plugin-react-virtualized";
import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
test: {
environment: 'jsdom',
environment: "jsdom",
globals: true,
setupFiles: ['./src/test/setup.ts']
setupFiles: ["./src/test/setup.ts"],
},
assetsInclude: ['**/*.wasm'],
plugins: [react(), wasm(), topLevelAwait(), VitePWA({
registerType: 'prompt',
manifest: {
name: 'Qortal Hub',
short_name: 'Hub',
description: 'Your easy access to the Qortal blockchain',
start_url: '/',
display: 'standalone',
theme_color: '#ffffff',
background_color: '#ffffff',
icons: [
{
src: '/qortal192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/qortal.png',
sizes: '512x512',
type: 'image/png',
},
],
},
workbox: {
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit
disableDevLogs: true, // Suppresses logs in development
},
})],
assetsInclude: ["**/*.wasm"],
plugins: [
react(),
wasm(),
topLevelAwait(),
VitePWA({
registerType: "prompt",
manifest: {
name: "Qortal Hub",
short_name: "Hub",
description: "Your easy access to the Qortal blockchain",
start_url: "/",
display: "standalone",
theme_color: "#ffffff",
background_color: "#ffffff",
icons: [
{
src: "/qortal192.png",
sizes: "192x192",
type: "image/png",
},
{
src: "/qortal.png",
sizes: "512x512",
type: "image/png",
},
],
},
workbox: {
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit
disableDevLogs: true, // Suppresses logs in development
},
}),
],
optimizeDeps: {
esbuildOptions: {
plugins: [fixReactVirtualized],
}
}
},
},
});