mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-02-15 19:55:50 +00:00
batch of updates 7
This commit is contained in:
parent
a4c1fd564b
commit
f6cac4b91f
45
package-lock.json
generated
45
package-lock.json
generated
@ -40,6 +40,7 @@
|
|||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"html-to-text": "^9.0.5",
|
"html-to-text": "^9.0.5",
|
||||||
"jssha": "3.3.1",
|
"jssha": "3.3.1",
|
||||||
|
"lit": "^3.2.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mime": "^4.0.4",
|
"mime": "^4.0.4",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
@ -1360,6 +1361,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
|
||||||
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
|
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@lit-labs/ssr-dom-shim": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@lit/reactive-element": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lit-labs/ssr-dom-shim": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@mui/base": {
|
"node_modules/@mui/base": {
|
||||||
"version": "5.0.0-beta.40",
|
"version": "5.0.0-beta.40",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
|
||||||
@ -2876,8 +2890,7 @@
|
|||||||
"node_modules/@types/trusted-types": {
|
"node_modules/@types/trusted-types": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/use-sync-external-store": {
|
"node_modules/@types/use-sync-external-store": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
@ -6029,6 +6042,34 @@
|
|||||||
"uc.micro": "^2.0.0"
|
"uc.micro": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lit": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lit/reactive-element": "^2.0.4",
|
||||||
|
"lit-element": "^4.1.0",
|
||||||
|
"lit-html": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lit-element": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lit-labs/ssr-dom-shim": "^1.2.0",
|
||||||
|
"@lit/reactive-element": "^2.0.4",
|
||||||
|
"lit-html": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lit-html": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/trusted-types": "^2.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/local-pkg": {
|
"node_modules/local-pkg": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
"react-virtuoso": "^4.10.4",
|
"react-virtuoso": "^4.10.4",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"short-unique-id": "^5.2.0",
|
"short-unique-id": "^5.2.0",
|
||||||
|
"lit": "^3.2.1",
|
||||||
"slate": "^0.103.0",
|
"slate": "^0.103.0",
|
||||||
"slate-react": "^0.109.0",
|
"slate-react": "^0.109.0",
|
||||||
"tiptap-extension-resize-image": "^1.1.8",
|
"tiptap-extension-resize-image": "^1.1.8",
|
||||||
|
@ -77,7 +77,7 @@ display: flex;
|
|||||||
border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5));
|
border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5));
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 140px;
|
width: auto;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
padding: 5px 15px 5px 15px;
|
padding: 5px 15px 5px 15px;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
175
src/App.tsx
175
src/App.tsx
@ -51,6 +51,7 @@ import {
|
|||||||
createAccount,
|
createAccount,
|
||||||
generateRandomSentence,
|
generateRandomSentence,
|
||||||
saveFileToDisk,
|
saveFileToDisk,
|
||||||
|
saveSeedPhraseToDisk
|
||||||
} from "./utils/generateWallet/generateWallet";
|
} from "./utils/generateWallet/generateWallet";
|
||||||
import { kdf } from "./deps/kdf";
|
import { kdf } from "./deps/kdf";
|
||||||
import { generateSaveWalletData } from "./utils/generateWallet/storeWallet";
|
import { generateSaveWalletData } from "./utils/generateWallet/storeWallet";
|
||||||
@ -116,6 +117,8 @@ import { useHandleTutorials } from "./components/Tutorials/useHandleTutorials";
|
|||||||
import { CoreSyncStatus } from "./components/CoreSyncStatus";
|
import { CoreSyncStatus } from "./components/CoreSyncStatus";
|
||||||
import BoundedNumericTextField from "./common/BoundedNumericTextField";
|
import BoundedNumericTextField from "./common/BoundedNumericTextField";
|
||||||
import { Wallets } from "./Wallets";
|
import { Wallets } from "./Wallets";
|
||||||
|
import './utils/seedPhrase/RandomSentenceGenerator';
|
||||||
|
import { test } from "vitest";
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
| "not-authenticated"
|
| "not-authenticated"
|
||||||
@ -323,7 +326,8 @@ function App() {
|
|||||||
const { isShow, onCancel, onOk, show, message } = useModal();
|
const { isShow, onCancel, onOk, show, message } = useModal();
|
||||||
const { isShow: isShowUnsavedChanges, onCancel: onCancelUnsavedChanges, onOk: onOkUnsavedChanges, show: showUnsavedChanges, message: messageUnsavedChanges } = useModal();
|
const { isShow: isShowUnsavedChanges, onCancel: onCancelUnsavedChanges, onOk: onOkUnsavedChanges, show: showUnsavedChanges, message: messageUnsavedChanges } = useModal();
|
||||||
const {downloadResource} = useFetchResources()
|
const {downloadResource} = useFetchResources()
|
||||||
|
const [showSeed, setShowSeed] = useState(false)
|
||||||
|
const [creationStep, setCreationStep] = useState(1)
|
||||||
const {
|
const {
|
||||||
isShow: isShowInfo,
|
isShow: isShowInfo,
|
||||||
onCancel: onCancelInfo,
|
onCancel: onCancelInfo,
|
||||||
@ -366,6 +370,11 @@ function App() {
|
|||||||
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
|
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
|
||||||
const resetAtomIsUsingImportExportSettingsAtom = useResetRecoilState(isUsingImportExportSettingsAtom)
|
const resetAtomIsUsingImportExportSettingsAtom = useResetRecoilState(isUsingImportExportSettingsAtom)
|
||||||
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
|
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
|
||||||
|
const generatorRef = useRef(null)
|
||||||
|
const exportSeedphrase = ()=> {
|
||||||
|
const seedPhrase = generatorRef.current.parsedString
|
||||||
|
saveSeedPhraseToDisk(seedPhrase)
|
||||||
|
}
|
||||||
const {showTutorial, openTutorialModal, shownTutorialsInitiated, setOpenTutorialModal} = useHandleTutorials()
|
const {showTutorial, openTutorialModal, shownTutorialsInitiated, setOpenTutorialModal} = useHandleTutorials()
|
||||||
|
|
||||||
const passwordRef = useRef<HTMLInputElement>(null);
|
const passwordRef = useRef<HTMLInputElement>(null);
|
||||||
@ -1028,7 +1037,8 @@ function App() {
|
|||||||
res();
|
res();
|
||||||
}, 250);
|
}, 250);
|
||||||
});
|
});
|
||||||
const res = await createAccount();
|
const res = await createAccount(generatorRef.current.parsedString);
|
||||||
|
|
||||||
const wallet = await res.generateSaveWalletData(
|
const wallet = await res.generateSaveWalletData(
|
||||||
walletToBeDownloadedPassword,
|
walletToBeDownloadedPassword,
|
||||||
crypto.kdfThreads,
|
crypto.kdfThreads,
|
||||||
@ -1102,6 +1112,8 @@ function App() {
|
|||||||
setExtstate("authenticated");
|
setExtstate("authenticated");
|
||||||
setIsOpenSendQort(false);
|
setIsOpenSendQort(false);
|
||||||
setIsOpenSendQortSuccess(false);
|
setIsOpenSendQortSuccess(false);
|
||||||
|
setShowSeed(false)
|
||||||
|
setCreationStep(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetAllStates = () => {
|
const resetAllStates = () => {
|
||||||
@ -1131,6 +1143,8 @@ function App() {
|
|||||||
setTxList([]);
|
setTxList([]);
|
||||||
setMemberGroups([]);
|
setMemberGroups([]);
|
||||||
resetAllRecoil()
|
resetAllRecoil()
|
||||||
|
setShowSeed(false)
|
||||||
|
setCreationStep(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
function roundUpToDecimals(number, decimals = 8) {
|
function roundUpToDecimals(number, decimals = 8) {
|
||||||
@ -1353,9 +1367,10 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<AuthenticatedContainer
|
<AuthenticatedContainer
|
||||||
sx={{
|
sx={{
|
||||||
width: isMobile ? "100vw" : "350px",
|
width: isMobile ? "100vw" : "auto",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
backgroundColor: "var(--bg-2)",
|
backgroundColor: "var(--bg-2)",
|
||||||
|
justifyContent: 'flex-end'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
@ -1378,11 +1393,13 @@ function App() {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<AuthenticatedContainerInnerLeft
|
{desktopViewMode !== "apps" && desktopViewMode !== "dev" && desktopViewMode !== "chat" && (
|
||||||
sx={{
|
<AuthenticatedContainerInnerLeft
|
||||||
overflowY: isMobile && "auto",
|
sx={{
|
||||||
}}
|
overflowY: isMobile && "auto",
|
||||||
>
|
padding: '0px 20px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Spacer height="48px" />
|
<Spacer height="48px" />
|
||||||
|
|
||||||
{authenticatedMode === "ltc" ? (
|
{authenticatedMode === "ltc" ? (
|
||||||
@ -1534,6 +1551,7 @@ function App() {
|
|||||||
Get QORT at Q-Trade
|
Get QORT at Q-Trade
|
||||||
</TextP>
|
</TextP>
|
||||||
</AuthenticatedContainerInnerLeft>
|
</AuthenticatedContainerInnerLeft>
|
||||||
|
)}
|
||||||
<AuthenticatedContainerInnerRight sx={{
|
<AuthenticatedContainerInnerRight sx={{
|
||||||
height: "100%",
|
height: "100%",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
@ -1620,7 +1638,7 @@ function App() {
|
|||||||
showTutorial('qapps', true)
|
showTutorial('qapps', true)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
showTutorial('create-account', true)
|
showTutorial('getting-started', true)
|
||||||
|
|
||||||
}
|
}
|
||||||
}} >
|
}} >
|
||||||
@ -1652,10 +1670,10 @@ function App() {
|
|||||||
<AppContainer
|
<AppContainer
|
||||||
sx={{
|
sx={{
|
||||||
height: isMobile ? "100%" : "100vh",
|
height: isMobile ? "100%" : "100vh",
|
||||||
backgroundImage: desktopViewMode === 'apps' && 'url("appsBg.svg")',
|
// backgroundImage: desktopViewMode === 'apps' && 'url("appsBg.svg")',
|
||||||
backgroundSize: desktopViewMode === 'apps' && 'cover',
|
// backgroundSize: desktopViewMode === 'apps' && 'cover',
|
||||||
backgroundPosition: desktopViewMode === 'apps' && 'center',
|
// backgroundPosition: desktopViewMode === 'apps' && 'center',
|
||||||
backgroundRepeat: desktopViewMode === 'apps' && 'no-repeat',
|
// backgroundRepeat: desktopViewMode === 'apps' && 'no-repeat',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GlobalContext.Provider value={{
|
<GlobalContext.Provider value={{
|
||||||
@ -1714,7 +1732,7 @@ function App() {
|
|||||||
desktopViewMode={desktopViewMode}
|
desktopViewMode={desktopViewMode}
|
||||||
setDesktopViewMode={setDesktopViewMode}
|
setDesktopViewMode={setDesktopViewMode}
|
||||||
/>
|
/>
|
||||||
{(!isMobile && desktopViewMode !== 'apps') && renderProfile()}
|
{!isMobile && renderProfile()}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
@ -2519,7 +2537,7 @@ function App() {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{extState === "create-wallet" && (
|
{extState === "create-wallet" && (
|
||||||
<>
|
<>
|
||||||
{!walletToBeDownloaded && (
|
{!walletToBeDownloaded && (
|
||||||
<>
|
<>
|
||||||
@ -2538,7 +2556,15 @@ function App() {
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if(creationStep === 2){
|
||||||
|
setCreationStep(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
setExtstate("not-authenticated");
|
setExtstate("not-authenticated");
|
||||||
|
setShowSeed(false)
|
||||||
|
setCreationStep(1)
|
||||||
|
setWalletToBeDownloadedPasswordConfirm('')
|
||||||
|
setWalletToBeDownloadedPassword('')
|
||||||
}}
|
}}
|
||||||
src={Return}
|
src={Return}
|
||||||
/>
|
/>
|
||||||
@ -2564,6 +2590,117 @@ function App() {
|
|||||||
Set up your Qortal account
|
Set up your Qortal account
|
||||||
</TextP>
|
</TextP>
|
||||||
<Spacer height="14px" />
|
<Spacer height="14px" />
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
maxWidth: '100%',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '10px'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: creationStep === 1 ? 'flex' : 'none',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '350px',
|
||||||
|
maxWidth: '95%'
|
||||||
|
}}>
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '14px'
|
||||||
|
}}>
|
||||||
|
A ‘ <span onClick={()=> {
|
||||||
|
setShowSeed(true)
|
||||||
|
}} style={{
|
||||||
|
fontSize: '14px',
|
||||||
|
color: 'steelblue',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}>SEEDPHRASE</span> ’ has been randomly generated in the background.
|
||||||
|
|
||||||
|
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '14px',
|
||||||
|
marginTop: '5px'
|
||||||
|
}}>
|
||||||
|
If you wish to VIEW THE SEEDPHRASE, click the word 'SEEDPHRASE' in this text. Seedphrases are used to generate the private key for your Qortal account. For security by default, seedphrases are NOT displayed unless specifically chosen.
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '16px',
|
||||||
|
marginTop: '15px',
|
||||||
|
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
Create your Qortal account by clicking <span style={{
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>NEXT</span> below.
|
||||||
|
|
||||||
|
</Typography>
|
||||||
|
<Spacer height="17px" />
|
||||||
|
<CustomButton onClick={()=> {
|
||||||
|
setCreationStep(2)
|
||||||
|
}}>
|
||||||
|
Next
|
||||||
|
</CustomButton>
|
||||||
|
</Box>
|
||||||
|
<div style={{
|
||||||
|
display: 'none'
|
||||||
|
}}>
|
||||||
|
<random-sentence-generator
|
||||||
|
ref={generatorRef}
|
||||||
|
template="adverb verb noun adjective noun adverb verb noun adjective noun adjective verbed adjective noun"
|
||||||
|
|
||||||
|
></random-sentence-generator>
|
||||||
|
</div>
|
||||||
|
<Dialog
|
||||||
|
open={showSeed}
|
||||||
|
aria-labelledby="alert-dialog-title"
|
||||||
|
aria-describedby="alert-dialog-description"
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<Box sx={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
maxWidth: '400px',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '10px',
|
||||||
|
display: showSeed ? 'flex' : 'none'
|
||||||
|
}}>
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '14px'
|
||||||
|
}}>Your seedphrase</Typography>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
textAlign: 'center',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: '#1f2023',
|
||||||
|
borderRadius: '5px',
|
||||||
|
padding: '10px',
|
||||||
|
}}>
|
||||||
|
{generatorRef.current?.parsedString}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<CustomButton sx={{
|
||||||
|
padding: '7px',
|
||||||
|
fontSize: '12px'
|
||||||
|
}} onClick={exportSeedphrase}>
|
||||||
|
Export Seedphrase
|
||||||
|
</CustomButton>
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
|
||||||
|
<Button variant="contained" onClick={()=> setShowSeed(false)}>
|
||||||
|
close
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: creationStep === 2 ? 'flex' : 'none',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
|
||||||
|
}}>
|
||||||
|
<Spacer height="14px" />
|
||||||
<CustomLabel htmlFor="standard-adornment-password">
|
<CustomLabel htmlFor="standard-adornment-password">
|
||||||
Wallet Password
|
Wallet Password
|
||||||
</CustomLabel>
|
</CustomLabel>
|
||||||
@ -2592,6 +2729,7 @@ function App() {
|
|||||||
<CustomButton onClick={createAccountFunc}>
|
<CustomButton onClick={createAccountFunc}>
|
||||||
Create Account
|
Create Account
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
|
</Box>
|
||||||
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -2611,9 +2749,12 @@ function App() {
|
|||||||
</TextP>
|
</TextP>
|
||||||
<Spacer height="100px" />
|
<Spacer height="100px" />
|
||||||
<CustomButton
|
<CustomButton
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
saveFileToDiskFunc();
|
await saveFileToDiskFunc();
|
||||||
returnToMain();
|
returnToMain();
|
||||||
|
await showInfo({
|
||||||
|
message: `Keep your wallet file secure.`,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Backup Account
|
Backup Account
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
|
||||||
import { Spacer } from "../common/Spacer";
|
import { Spacer } from "../common/Spacer";
|
||||||
import { CustomButton, TextItalic, TextP, TextSpan } from "../App-styles";
|
import { CustomButton, TextItalic, TextP, TextSpan } from "../App-styles";
|
||||||
import {
|
import {
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
|
ButtonBase
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import Logo1 from "../assets/svgs/Logo1.svg";
|
import Logo1 from "../assets/svgs/Logo1.svg";
|
||||||
import Logo1Dark from "../assets/svgs/Logo1Dark.svg";
|
import Logo1Dark from "../assets/svgs/Logo1Dark.svg";
|
||||||
@ -21,6 +22,8 @@ import Info from "../assets/svgs/Info.svg";
|
|||||||
import { CustomizedSnackbars } from "../components/Snackbar/Snackbar";
|
import { CustomizedSnackbars } from "../components/Snackbar/Snackbar";
|
||||||
import { set } from "lodash";
|
import { set } from "lodash";
|
||||||
import { cleanUrl, isUsingLocal } from "../background";
|
import { cleanUrl, isUsingLocal } from "../background";
|
||||||
|
import HelpIcon from '@mui/icons-material/Help';
|
||||||
|
import { GlobalContext } from "../App";
|
||||||
|
|
||||||
const manifestData = chrome?.runtime?.getManifest();
|
const manifestData = chrome?.runtime?.getManifest();
|
||||||
|
|
||||||
@ -55,6 +58,8 @@ export const NotAuthenticated = ({
|
|||||||
const importedApiKeyRef = useRef(null)
|
const importedApiKeyRef = useRef(null)
|
||||||
const currentNodeRef = useRef(null)
|
const currentNodeRef = useRef(null)
|
||||||
const hasLocalNodeRef = useRef(null)
|
const hasLocalNodeRef = useRef(null)
|
||||||
|
const { showTutorial } = useContext(GlobalContext);
|
||||||
|
|
||||||
const isLocal = cleanUrl(currentNode?.url) === "127.0.0.1:12391";
|
const isLocal = cleanUrl(currentNode?.url) === "127.0.0.1:12391";
|
||||||
const handleFileChangeApiKey = (event) => {
|
const handleFileChangeApiKey = (event) => {
|
||||||
const file = event.target.files[0]; // Get the selected file
|
const file = event.target.files[0]; // Get the selected file
|
||||||
@ -627,6 +632,17 @@ export const NotAuthenticated = ({
|
|||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
|
<ButtonBase onClick={()=> {
|
||||||
|
showTutorial('create-account', true)
|
||||||
|
}} sx={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: '25px',
|
||||||
|
right: '25px'
|
||||||
|
}}>
|
||||||
|
<HelpIcon sx={{
|
||||||
|
color: 'var(--unread)'
|
||||||
|
}} />
|
||||||
|
</ButtonBase>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -34,46 +34,8 @@ import { RESOURCE_TYPE_NUMBER_GROUP_CHAT_REACTIONS } from "./constants/resourceT
|
|||||||
import TradeBotRespondRequest from './transactions/TradeBotRespondRequest';
|
import TradeBotRespondRequest from './transactions/TradeBotRespondRequest';
|
||||||
|
|
||||||
|
|
||||||
let inMemoryKey: CryptoKey | null = null;
|
|
||||||
let inMemoryIV: Uint8Array | null = null;
|
|
||||||
|
|
||||||
|
|
||||||
async function initializeKeyAndIV() {
|
|
||||||
if (!inMemoryKey) {
|
|
||||||
inMemoryKey = await generateKey(); // Generates the key in memory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function generateKey(): Promise<CryptoKey> {
|
|
||||||
return await crypto.subtle.generateKey(
|
|
||||||
{
|
|
||||||
name: "AES-GCM",
|
|
||||||
length: 256
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
["encrypt", "decrypt"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function encryptData(data: string, key: CryptoKey): Promise<{ iv: Uint8Array; encryptedData: ArrayBuffer }> {
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
const encodedData = encoder.encode(data);
|
|
||||||
|
|
||||||
// Generate a random IV each time you encrypt
|
|
||||||
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
||||||
|
|
||||||
const encryptedData = await crypto.subtle.encrypt(
|
|
||||||
{
|
|
||||||
name: "AES-GCM",
|
|
||||||
iv: iv
|
|
||||||
},
|
|
||||||
key,
|
|
||||||
encodedData
|
|
||||||
);
|
|
||||||
|
|
||||||
return { iv, encryptedData };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cleanUrl(url) {
|
export function cleanUrl(url) {
|
||||||
return url?.replace(/^(https?:\/\/)?(www\.)?/, '');
|
return url?.replace(/^(https?:\/\/)?(www\.)?/, '');
|
||||||
}
|
}
|
||||||
@ -1064,15 +1026,7 @@ function base64ToJson(base64) {
|
|||||||
export async function getKeyPair() {
|
export async function getKeyPair() {
|
||||||
const res = await chrome.storage.local.get(["keyPair"]);
|
const res = await chrome.storage.local.get(["keyPair"]);
|
||||||
if (res?.keyPair) {
|
if (res?.keyPair) {
|
||||||
const combinedData = atob(res?.keyPair)
|
return res.keyPair;
|
||||||
.split("")
|
|
||||||
.map((c) => c.charCodeAt(0));
|
|
||||||
|
|
||||||
const iv = new Uint8Array(combinedData.slice(0, 12)); // First 12 bytes are the IV
|
|
||||||
const encryptedData = new Uint8Array(combinedData.slice(12)).buffer;
|
|
||||||
|
|
||||||
const decryptedBase64Data = await decryptData(encryptedData, inMemoryKey, iv);
|
|
||||||
return decryptedBase64Data
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Wallet not authenticated");
|
throw new Error("Wallet not authenticated");
|
||||||
}
|
}
|
||||||
@ -1573,14 +1527,8 @@ async function decryptWallet({ password, wallet, walletVersion }) {
|
|||||||
rvnPrivateKey: wallet2._addresses[0].rvnWallet.derivedMasterPrivateKey
|
rvnPrivateKey: wallet2._addresses[0].rvnWallet.derivedMasterPrivateKey
|
||||||
};
|
};
|
||||||
const dataString = JSON.stringify(toSave);
|
const dataString = JSON.stringify(toSave);
|
||||||
await initializeKeyAndIV();
|
|
||||||
const { iv, encryptedData } = await encryptData(dataString, inMemoryKey);
|
|
||||||
|
|
||||||
// Combine IV and encrypted data into a single Uint8Array
|
|
||||||
const combinedData = new Uint8Array([...iv, ...new Uint8Array(encryptedData)]);
|
|
||||||
const encryptedBase64Data = btoa(String.fromCharCode(...combinedData));
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
chrome.storage.local.set({ keyPair: encryptedBase64Data }, () => {
|
chrome.storage.local.set({ keyPair: dataString }, () => {
|
||||||
if (chrome.runtime.lastError) {
|
if (chrome.runtime.lastError) {
|
||||||
reject(new Error(chrome.runtime.lastError.message));
|
reject(new Error(chrome.runtime.lastError.message));
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,10 +20,12 @@ import { HomeIcon } from "../../assets/Icons/HomeIcon";
|
|||||||
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||||
import { Save } from "../Save/Save";
|
import { Save } from "../Save/Save";
|
||||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||||
|
import { IconWrapper } from "../Desktop/DesktopFooter";
|
||||||
|
import { AppsIcon } from "../../assets/Icons/AppsIcon";
|
||||||
|
|
||||||
const uid = new ShortUniqueId({ length: 8 });
|
const uid = new ShortUniqueId({ length: 8 });
|
||||||
|
|
||||||
export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktopSideView, hasUnreadDirects, isDirects, isGroups, hasUnreadGroups, toggleSideViewGroups, toggleSideViewDirects}) => {
|
export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktopSideView, hasUnreadDirects, isDirects, isGroups, hasUnreadGroups, toggleSideViewGroups, toggleSideViewDirects, setDesktopViewMode, isApps, desktopViewMode}) => {
|
||||||
const [availableQapps, setAvailableQapps] = useState([]);
|
const [availableQapps, setAvailableQapps] = useState([]);
|
||||||
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
|
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
|
||||||
const [selectedCategory, setSelectedCategory] = useState(null)
|
const [selectedCategory, setSelectedCategory] = useState(null)
|
||||||
@ -334,46 +336,44 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
|
|||||||
|
|
||||||
<HomeIcon
|
<HomeIcon
|
||||||
height={34}
|
height={34}
|
||||||
color="rgba(250, 250, 250, 0.5)"
|
color={desktopViewMode === 'home' ? 'white': "rgba(250, 250, 250, 0.5)"}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDesktopSideView("directs");
|
setDesktopViewMode('apps')
|
||||||
toggleSideViewDirects()
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<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)"}
|
||||||
|
label="Chat"
|
||||||
|
disableWidth
|
||||||
|
>
|
||||||
<MessagingIcon
|
<MessagingIcon
|
||||||
height={30}
|
height={30}
|
||||||
color={
|
color={
|
||||||
hasUnreadDirects
|
(hasUnreadDirects || hasUnreadGroups)
|
||||||
? "var(--unread)"
|
? "var(--unread)"
|
||||||
: isDirects
|
: desktopViewMode === 'chat'
|
||||||
? "white"
|
? "white"
|
||||||
: "rgba(250, 250, 250, 0.5)"
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</IconWrapper>
|
||||||
</ButtonBase>
|
|
||||||
<ButtonBase
|
|
||||||
onClick={() => {
|
|
||||||
setDesktopSideView("groups");
|
|
||||||
toggleSideViewGroups()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<HubsIcon
|
|
||||||
height={30}
|
|
||||||
color={
|
|
||||||
hasUnreadGroups
|
|
||||||
? "var(--unread)"
|
|
||||||
: isGroups
|
|
||||||
? "white"
|
|
||||||
: "rgba(250, 250, 250, 0.5)"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<Save isDesktop myName={myName} />
|
<Save isDesktop myName={myName} />
|
||||||
{mode !== 'home' && (
|
{mode !== 'home' && (
|
||||||
|
@ -18,7 +18,7 @@ import AppIcon from "../../assets/svgs/AppIcon.svg";
|
|||||||
import { HomeIcon } from "../../assets/Icons/HomeIcon";
|
import { HomeIcon } from "../../assets/Icons/HomeIcon";
|
||||||
import { Save } from "../Save/Save";
|
import { Save } from "../Save/Save";
|
||||||
|
|
||||||
export const IconWrapper = ({ children, label, color, selected }) => {
|
export const IconWrapper = ({ children, label, color, selected, disableWidth, customWidth }) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -27,8 +27,8 @@ export const IconWrapper = ({ children, label, color, selected }) => {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "5px",
|
gap: "5px",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
height: "89px",
|
height: customWidth ? customWidth : disableWidth ? 'auto' : "89px",
|
||||||
width: "89px",
|
width: customWidth? customWidth : disableWidth ? 'auto' : "89px",
|
||||||
borderRadius: "50%",
|
borderRadius: "50%",
|
||||||
backgroundColor: selected ? "rgba(28, 29, 32, 1)" : "transparent",
|
backgroundColor: selected ? "rgba(28, 29, 32, 1)" : "transparent",
|
||||||
}}
|
}}
|
||||||
|
@ -128,74 +128,7 @@ export const DesktopHeader = ({
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonBase
|
|
||||||
onClick={() => {
|
|
||||||
goToHome();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<IconWrapper
|
|
||||||
color="rgba(250, 250, 250, 0.5)"
|
|
||||||
label="Home"
|
|
||||||
selected={isHome}
|
|
||||||
>
|
|
||||||
<HomeIcon
|
|
||||||
height={25}
|
|
||||||
color={isHome ? "white" : "rgba(250, 250, 250, 0.5)"}
|
|
||||||
/>
|
|
||||||
</IconWrapper>
|
|
||||||
</ButtonBase>
|
|
||||||
<ButtonBase
|
|
||||||
onClick={() => {
|
|
||||||
setDesktopSideView("groups");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<IconWrapper
|
|
||||||
color="rgba(250, 250, 250, 0.5)"
|
|
||||||
label="Groups"
|
|
||||||
selected={isGroups}
|
|
||||||
>
|
|
||||||
<HubsIcon
|
|
||||||
height={25}
|
|
||||||
color={
|
|
||||||
hasUnreadGroups
|
|
||||||
? "var(--unread)"
|
|
||||||
: isGroups
|
|
||||||
? "white"
|
|
||||||
: "rgba(250, 250, 250, 0.5)"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</IconWrapper>
|
|
||||||
</ButtonBase>
|
|
||||||
<ButtonBase
|
|
||||||
onClick={() => {
|
|
||||||
setDesktopSideView("directs");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<IconWrapper
|
|
||||||
color="rgba(250, 250, 250, 0.5)"
|
|
||||||
label="Messaging"
|
|
||||||
selected={isDirects}
|
|
||||||
>
|
|
||||||
<MessagingIcon
|
|
||||||
height={25}
|
|
||||||
color={
|
|
||||||
hasUnreadDirects
|
|
||||||
? "var(--unread)"
|
|
||||||
: isDirects
|
|
||||||
? "white"
|
|
||||||
: "rgba(250, 250, 250, 0.5)"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</IconWrapper>
|
|
||||||
</ButtonBase>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "1px",
|
|
||||||
height: "50px",
|
|
||||||
background: "white",
|
|
||||||
borderRadius: "50px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
goToAnnouncements()
|
goToAnnouncements()
|
||||||
@ -231,6 +164,7 @@ export const DesktopHeader = ({
|
|||||||
label="Chat"
|
label="Chat"
|
||||||
selected={isChat}
|
selected={isChat}
|
||||||
selectColor="#09b6e8"
|
selectColor="#09b6e8"
|
||||||
|
customHeight="55px"
|
||||||
>
|
>
|
||||||
<ChatIcon
|
<ChatIcon
|
||||||
height={25}
|
height={25}
|
||||||
@ -257,6 +191,7 @@ export const DesktopHeader = ({
|
|||||||
label="Threads"
|
label="Threads"
|
||||||
selected={isForum}
|
selected={isForum}
|
||||||
selectColor="#09b6e8"
|
selectColor="#09b6e8"
|
||||||
|
customHeight="55px"
|
||||||
>
|
>
|
||||||
<ThreadsIcon
|
<ThreadsIcon
|
||||||
height={25}
|
height={25}
|
||||||
@ -279,6 +214,7 @@ export const DesktopHeader = ({
|
|||||||
color="rgba(250, 250, 250, 0.5)"
|
color="rgba(250, 250, 250, 0.5)"
|
||||||
label="Members"
|
label="Members"
|
||||||
selected={false}
|
selected={false}
|
||||||
|
customHeight="55px"
|
||||||
>
|
>
|
||||||
<MembersIcon
|
<MembersIcon
|
||||||
height={25}
|
height={25}
|
||||||
|
104
src/components/DesktopSideBar.tsx
Normal file
104
src/components/DesktopSideBar.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { Box, ButtonBase } from '@mui/material';
|
||||||
|
import React from 'react'
|
||||||
|
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 { AppsIcon } from '../assets/Icons/AppsIcon';
|
||||||
|
|
||||||
|
export const DesktopSideBar = ({goToHome, setDesktopSideView, toggleSideViewDirects, hasUnreadDirects, isDirects, toggleSideViewGroups,hasUnreadGroups, isGroups, isApps, setDesktopViewMode, desktopViewMode, myName }) => {
|
||||||
|
|
||||||
|
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')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<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
|
||||||
|
onClick={() => {
|
||||||
|
setDesktopSideView("groups");
|
||||||
|
toggleSideViewGroups()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HubsIcon
|
||||||
|
height={30}
|
||||||
|
color={
|
||||||
|
hasUnreadGroups
|
||||||
|
? "var(--danger)"
|
||||||
|
: isGroups
|
||||||
|
? "white"
|
||||||
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</ButtonBase> */}
|
||||||
|
<Save isDesktop disableWidth myName={myName} />
|
||||||
|
{/* <CoreSyncStatus imageSize="30px" position="left" /> */}
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
@ -86,7 +86,7 @@ import { getRootHeight } from "../../utils/mobile/mobileUtils";
|
|||||||
import { ReturnIcon } from "../../assets/Icons/ReturnIcon";
|
import { ReturnIcon } from "../../assets/Icons/ReturnIcon";
|
||||||
import { ExitIcon } from "../../assets/Icons/ExitIcon";
|
import { ExitIcon } from "../../assets/Icons/ExitIcon";
|
||||||
import { HomeDesktop } from "./HomeDesktop";
|
import { HomeDesktop } from "./HomeDesktop";
|
||||||
import { DesktopFooter } from "../Desktop/DesktopFooter";
|
import { DesktopFooter, IconWrapper } from "../Desktop/DesktopFooter";
|
||||||
import { DesktopHeader } from "../Desktop/DesktopHeader";
|
import { DesktopHeader } from "../Desktop/DesktopHeader";
|
||||||
import { Apps } from "../Apps/Apps";
|
import { Apps } from "../Apps/Apps";
|
||||||
import { AppsNavBar } from "../Apps/AppsNavBar";
|
import { AppsNavBar } from "../Apps/AppsNavBar";
|
||||||
@ -98,6 +98,9 @@ import { useSetRecoilState } from "recoil";
|
|||||||
import { selectedGroupIdAtom } from "../../atoms/global";
|
import { selectedGroupIdAtom } from "../../atoms/global";
|
||||||
import { sortArrayByTimestampAndGroupName } from "../../utils/time";
|
import { sortArrayByTimestampAndGroupName } from "../../utils/time";
|
||||||
import { AdminSpace } from "../Chat/AdminSpace";
|
import { AdminSpace } from "../Chat/AdminSpace";
|
||||||
|
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||||
|
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||||
|
import { DesktopSideBar } from "../DesktopSideBar";
|
||||||
|
|
||||||
// let touchStartY = 0;
|
// let touchStartY = 0;
|
||||||
// let disablePullToRefresh = false;
|
// let disablePullToRefresh = false;
|
||||||
@ -1359,6 +1362,10 @@ export const Group = ({
|
|||||||
setupGroupWebsocketInterval.current = null;
|
setupGroupWebsocketInterval.current = null;
|
||||||
settimeoutForRefetchSecretKey.current = null;
|
settimeoutForRefetchSecretKey.current = null;
|
||||||
initiatedGetMembers.current = false;
|
initiatedGetMembers.current = false;
|
||||||
|
|
||||||
|
if(!isMobile){
|
||||||
|
setDesktopViewMode('home')
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openDevModeFunc = () => {
|
const openDevModeFunc = () => {
|
||||||
@ -1445,7 +1452,9 @@ export const Group = ({
|
|||||||
setTriedToFetchSecretKey(false);
|
setTriedToFetchSecretKey(false);
|
||||||
setFirstSecretKeyInCreation(false);
|
setFirstSecretKeyInCreation(false);
|
||||||
setGroupSection("chat");
|
setGroupSection("chat");
|
||||||
|
if(!isMobile){
|
||||||
|
setDesktopViewMode('chat')
|
||||||
|
}
|
||||||
chrome?.runtime?.sendMessage({
|
chrome?.runtime?.sendMessage({
|
||||||
action: "addTimestampEnterChat",
|
action: "addTimestampEnterChat",
|
||||||
payload: {
|
payload: {
|
||||||
@ -1458,7 +1467,6 @@ export const Group = ({
|
|||||||
setSelectedGroup(findGroup);
|
setSelectedGroup(findGroup);
|
||||||
setMobileViewMode("group");
|
setMobileViewMode("group");
|
||||||
setDesktopSideView('groups')
|
setDesktopSideView('groups')
|
||||||
setDesktopViewMode('home')
|
|
||||||
getTimestampEnterChat();
|
getTimestampEnterChat();
|
||||||
isLoadingOpenSectionFromNotification.current = false;
|
isLoadingOpenSectionFromNotification.current = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
@ -1497,6 +1505,9 @@ export const Group = ({
|
|||||||
setTriedToFetchSecretKey(false);
|
setTriedToFetchSecretKey(false);
|
||||||
setFirstSecretKeyInCreation(false);
|
setFirstSecretKeyInCreation(false);
|
||||||
setGroupSection("announcement");
|
setGroupSection("announcement");
|
||||||
|
if(!isMobile){
|
||||||
|
setDesktopViewMode('chat')
|
||||||
|
}
|
||||||
chrome?.runtime?.sendMessage({
|
chrome?.runtime?.sendMessage({
|
||||||
action: "addGroupNotificationTimestamp",
|
action: "addGroupNotificationTimestamp",
|
||||||
payload: {
|
payload: {
|
||||||
@ -1508,7 +1519,6 @@ export const Group = ({
|
|||||||
setSelectedGroup(findGroup);
|
setSelectedGroup(findGroup);
|
||||||
setMobileViewMode("group");
|
setMobileViewMode("group");
|
||||||
setDesktopSideView('groups')
|
setDesktopSideView('groups')
|
||||||
setDesktopViewMode('home')
|
|
||||||
getGroupAnnouncements();
|
getGroupAnnouncements();
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
@ -1560,12 +1570,13 @@ export const Group = ({
|
|||||||
setFirstSecretKeyInCreation(false);
|
setFirstSecretKeyInCreation(false);
|
||||||
setGroupSection("forum");
|
setGroupSection("forum");
|
||||||
setDefaultThread(data);
|
setDefaultThread(data);
|
||||||
|
if(!isMobile){
|
||||||
|
setDesktopViewMode('chat')
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setSelectedGroup(findGroup);
|
setSelectedGroup(findGroup);
|
||||||
setMobileViewMode("group");
|
setMobileViewMode("group");
|
||||||
setDesktopSideView('groups')
|
setDesktopSideView('groups')
|
||||||
setDesktopViewMode('home')
|
|
||||||
getGroupAnnouncements();
|
getGroupAnnouncements();
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
@ -1591,32 +1602,13 @@ export const Group = ({
|
|||||||
}
|
}
|
||||||
setDesktopViewMode('home')
|
setDesktopViewMode('home')
|
||||||
|
|
||||||
setGroupSection("default");
|
|
||||||
clearAllQueues();
|
|
||||||
await new Promise((res) => {
|
await new Promise((res) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
res(null);
|
res(null);
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
setGroupSection("home");
|
|
||||||
setSelectedGroup(null);
|
|
||||||
setNewChat(false);
|
|
||||||
setSelectedDirect(null);
|
|
||||||
setSecretKey(null);
|
|
||||||
setGroupOwner(null)
|
|
||||||
lastFetchedSecretKey.current = null;
|
|
||||||
initiatedGetMembers.current = false;
|
|
||||||
setSecretKeyPublishDate(null);
|
|
||||||
setAdmins([]);
|
|
||||||
setSecretKeyDetails(null);
|
|
||||||
setAdminsWithNames([]);
|
|
||||||
setMembers([]);
|
|
||||||
setMemberCountFromSecretKeyData(null);
|
|
||||||
setIsForceShowCreationKeyPopup(false)
|
|
||||||
setTriedToFetchSecretKey(false);
|
|
||||||
setFirstSecretKeyInCreation(false);
|
|
||||||
setIsOpenSideViewDirects(false)
|
|
||||||
setIsOpenSideViewGroups(false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const goToAnnouncements = async () => {
|
const goToAnnouncements = async () => {
|
||||||
@ -1690,6 +1682,66 @@ export const Group = ({
|
|||||||
borderRadius: !isMobile && '0px 15px 15px 0px'
|
borderRadius: !isMobile && '0px 15px 15px 0px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{!isMobile && (
|
||||||
|
<Box sx={{
|
||||||
|
width: '100%',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
gap: '10px'
|
||||||
|
}}>
|
||||||
|
<ButtonBase
|
||||||
|
onClick={() => {
|
||||||
|
setDesktopSideView("groups");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconWrapper
|
||||||
|
color={(groupChatHasUnread ||
|
||||||
|
groupsAnnHasUnread)
|
||||||
|
? "var(--unread)"
|
||||||
|
: desktopSideView === 'groups' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||||
|
label="Groups"
|
||||||
|
selected={desktopSideView === 'groups'}
|
||||||
|
customWidth="75px"
|
||||||
|
>
|
||||||
|
<HubsIcon
|
||||||
|
height={24}
|
||||||
|
color={
|
||||||
|
(groupChatHasUnread ||
|
||||||
|
groupsAnnHasUnread)
|
||||||
|
? "var(--unread)"
|
||||||
|
: desktopSideView === 'groups'
|
||||||
|
? "white"
|
||||||
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</IconWrapper>
|
||||||
|
</ButtonBase>
|
||||||
|
<ButtonBase
|
||||||
|
onClick={() => {
|
||||||
|
setDesktopSideView("directs");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconWrapper
|
||||||
|
customWidth="75px"
|
||||||
|
color={directChatHasUnread ? "var(--unread)" : desktopSideView === 'directs' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||||
|
label="Messaging"
|
||||||
|
selected={desktopSideView === 'directs'}
|
||||||
|
>
|
||||||
|
<MessagingIcon
|
||||||
|
height={24}
|
||||||
|
color={
|
||||||
|
directChatHasUnread
|
||||||
|
? "var(--unread)"
|
||||||
|
: desktopSideView === 'directs'
|
||||||
|
? "white"
|
||||||
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</IconWrapper>
|
||||||
|
</ButtonBase>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -1899,172 +1951,66 @@ export const Group = ({
|
|||||||
borderRadius: !isMobile && '0px 15px 15px 0px'
|
borderRadius: !isMobile && '0px 15px 15px 0px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* <div
|
{!isMobile && (
|
||||||
style={{
|
<Box sx={{
|
||||||
display: "flex",
|
width: '100%',
|
||||||
width: "100%",
|
alignItems: 'center',
|
||||||
justifyContent: "center",
|
justifyContent: 'center',
|
||||||
gap: "20px",
|
display: 'flex',
|
||||||
padding: "10px",
|
gap: '10px'
|
||||||
flexDirection: "column",
|
}}>
|
||||||
}}
|
<ButtonBase
|
||||||
>
|
|
||||||
{isMobile && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloseIcon
|
|
||||||
onClick={() => {
|
|
||||||
setIsOpenDrawer(false);
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
cursor: "pointer",
|
|
||||||
color: "white",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<CustomButton
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setChatMode((prev) =>
|
setDesktopSideView("groups");
|
||||||
prev === "directs" ? "groups" : "directs"
|
|
||||||
);
|
|
||||||
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
backgroundColor: chatMode === 'directs' && ( groupChatHasUnread || groupsAnnHasUnread) ? 'red' : 'revert'
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{chatMode === "groups" && (
|
<IconWrapper
|
||||||
<>
|
color={(groupChatHasUnread ||
|
||||||
<MarkUnreadChatAltIcon
|
groupsAnnHasUnread)
|
||||||
sx={{
|
? "var(--unread)"
|
||||||
color: directChatHasUnread ? "red" : "white",
|
: desktopSideView === 'groups' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||||
}}
|
label="Groups"
|
||||||
/>
|
selected={desktopSideView === 'groups'}
|
||||||
</>
|
customWidth="75px"
|
||||||
)}
|
>
|
||||||
|
<HubsIcon
|
||||||
{chatMode === "directs" ? "Switch to groups" : "Direct msgs"}
|
height={24}
|
||||||
</CustomButton>
|
color={
|
||||||
</div> */}
|
(groupChatHasUnread ||
|
||||||
{/* <div
|
groupsAnnHasUnread)
|
||||||
style={{
|
? "var(--unread)"
|
||||||
display: "flex",
|
: desktopSideView === 'groups'
|
||||||
width: "100%",
|
? "white"
|
||||||
flexDirection: "column",
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
alignItems: "flex-start",
|
}
|
||||||
flexGrow: 1,
|
/>
|
||||||
overflowY: "auto",
|
</IconWrapper>
|
||||||
visibility: chatMode === "groups" && "hidden",
|
</ButtonBase>
|
||||||
position: chatMode === "groups" && "fixed",
|
<ButtonBase
|
||||||
left: chatMode === "groups" && "-1000px",
|
onClick={() => {
|
||||||
}}
|
setDesktopSideView("directs");
|
||||||
>
|
}}
|
||||||
{directs.map((direct: any) => (
|
>
|
||||||
<List sx={{
|
<IconWrapper
|
||||||
width: '100%'
|
customWidth="75px"
|
||||||
}} className="group-list" dense={true}>
|
color={directChatHasUnread ? "var(--unread)" : desktopSideView === 'directs' ? 'white' :"rgba(250, 250, 250, 0.5)"}
|
||||||
<ListItem
|
label="Messaging"
|
||||||
// secondaryAction={
|
selected={desktopSideView === 'directs' }
|
||||||
// <IconButton edge="end" aria-label="delete">
|
>
|
||||||
// <SettingsIcon />
|
<MessagingIcon
|
||||||
// </IconButton>
|
height={24}
|
||||||
// }
|
color={
|
||||||
onClick={() => {
|
directChatHasUnread
|
||||||
setSelectedDirect(null);
|
? "var(--unread)"
|
||||||
setNewChat(false);
|
: desktopSideView === 'directs'
|
||||||
// setSelectedGroup(null);
|
? "white"
|
||||||
setIsOpenDrawer(false);
|
: "rgba(250, 250, 250, 0.5)"
|
||||||
chrome?.runtime?.sendMessage({
|
}
|
||||||
action: "addTimestampEnterChat",
|
/>
|
||||||
payload: {
|
</IconWrapper>
|
||||||
timestamp: Date.now(),
|
</ButtonBase>
|
||||||
groupId: direct.address,
|
</Box>
|
||||||
},
|
)}
|
||||||
});
|
|
||||||
setTimeout(() => {
|
|
||||||
setSelectedDirect(direct);
|
|
||||||
|
|
||||||
getTimestampEnterChat();
|
|
||||||
}, 200);
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
width: "100%",
|
|
||||||
flexDirection: "column",
|
|
||||||
cursor: "pointer",
|
|
||||||
border: "1px #232428 solid",
|
|
||||||
padding: "2px",
|
|
||||||
borderRadius: "2px",
|
|
||||||
background:
|
|
||||||
direct?.address === selectedDirect?.address && "white",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar
|
|
||||||
sx={{
|
|
||||||
background: "#232428",
|
|
||||||
color: "white",
|
|
||||||
}}
|
|
||||||
alt={direct?.name || direct?.address}
|
|
||||||
// src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${groupOwner?.name}/qortal_group_avatar_${group.groupId}?async=true`}
|
|
||||||
>
|
|
||||||
{(direct?.name || direct?.address)?.charAt(0)}
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary={direct?.name || direct?.address}
|
|
||||||
primaryTypographyProps={{
|
|
||||||
style: {
|
|
||||||
color:
|
|
||||||
direct?.address === selectedDirect?.address &&
|
|
||||||
"black",
|
|
||||||
textWrap: "wrap",
|
|
||||||
overflow: "hidden",
|
|
||||||
},
|
|
||||||
}} // Change the color of the primary text
|
|
||||||
secondaryTypographyProps={{
|
|
||||||
style: {
|
|
||||||
color:
|
|
||||||
direct?.address === selectedDirect?.address &&
|
|
||||||
"black",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
width: "150px",
|
|
||||||
fontFamily: "Inter",
|
|
||||||
fontSize: "16px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{direct?.sender !== myAddress &&
|
|
||||||
direct?.timestamp &&
|
|
||||||
((!timestampEnterData[direct?.address] &&
|
|
||||||
Date.now() - direct?.timestamp <
|
|
||||||
timeDifferenceForNotificationChats) ||
|
|
||||||
timestampEnterData[direct?.address] <
|
|
||||||
direct?.timestamp) && (
|
|
||||||
<MarkChatUnreadIcon
|
|
||||||
sx={{
|
|
||||||
color: "red",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</ListItem>
|
|
||||||
</List>
|
|
||||||
))}
|
|
||||||
</div> */}
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -2095,7 +2041,6 @@ export const Group = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setMobileViewMode("group");
|
setMobileViewMode("group");
|
||||||
setDesktopSideView('groups')
|
setDesktopSideView('groups')
|
||||||
setDesktopViewMode('home')
|
|
||||||
initiatedGetMembers.current = false;
|
initiatedGetMembers.current = false;
|
||||||
clearAllQueues();
|
clearAllQueues();
|
||||||
setSelectedDirect(null);
|
setSelectedDirect(null);
|
||||||
@ -2347,8 +2292,14 @@ export const Group = ({
|
|||||||
alignItems: "flex-start",
|
alignItems: "flex-start",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{!isMobile && ((desktopSideView === 'groups' && desktopViewMode !== 'apps') || isOpenSideViewGroups) && renderGroups()}
|
{!isMobile && ((desktopViewMode !== 'apps' && desktopViewMode !== 'dev') || isOpenSideViewGroups) && (
|
||||||
{!isMobile && ((desktopSideView === 'directs' && desktopViewMode !== 'apps') || isOpenSideViewDirects) && renderDirects()}
|
<DesktopSideBar desktopViewMode={desktopViewMode} toggleSideViewGroups={toggleSideViewGroups} toggleSideViewDirects={toggleSideViewDirects} goToHome={goToHome} mode={appsMode} setMode={setAppsMode} setDesktopSideView={setDesktopSideView} hasUnreadDirects={directChatHasUnread} isApps={desktopViewMode === 'apps'} myName={userInfo?.name} isGroups={isOpenSideViewGroups}
|
||||||
|
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
|
||||||
|
groupsAnnHasUnread} setDesktopViewMode={setDesktopViewMode} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isMobile && desktopViewMode === 'chat' && desktopSideView !== 'directs' && renderGroups()}
|
||||||
|
{!isMobile && desktopViewMode === 'chat' && desktopSideView === 'directs' && renderDirects()}
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -2454,9 +2405,37 @@ export const Group = ({
|
|||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{selectedGroup && mobileViewMode !== 'groups' && (
|
{desktopViewMode === 'chat' && !selectedGroup && (
|
||||||
<>
|
<Box
|
||||||
{!isMobile && selectedGroup && (
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '100%',
|
||||||
|
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "14px",
|
||||||
|
fontWeight: 400,
|
||||||
|
color: 'rgba(255, 255, 255, 0.2)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
No group selected
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{mobileViewMode !== 'groups' && (
|
||||||
|
<div style={{
|
||||||
|
width: '100%',
|
||||||
|
display: selectedGroup? 'block' : 'none',
|
||||||
|
opacity: !(desktopViewMode === 'chat' && selectedGroup) ? 0 : 1,
|
||||||
|
position: !(desktopViewMode === 'chat' && selectedGroup) ? 'absolute' : 'relative',
|
||||||
|
left: !(desktopViewMode === 'chat' && selectedGroup) ? '-100000px' : '0px',
|
||||||
|
}}>
|
||||||
|
{!isMobile && (
|
||||||
|
|
||||||
<DesktopHeader
|
<DesktopHeader
|
||||||
isPrivate={isPrivate}
|
isPrivate={isPrivate}
|
||||||
@ -2753,7 +2732,7 @@ export const Group = ({
|
|||||||
isOwner={groupOwner?.owner === myAddress}
|
isOwner={groupOwner?.owner === myAddress}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{selectedDirect && !newChat && (
|
{selectedDirect && !newChat && (
|
||||||
@ -2797,43 +2776,7 @@ export const Group = ({
|
|||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isMobile && groupSection === "home" && (
|
|
||||||
<DesktopFooter
|
|
||||||
isPrivate={isPrivate}
|
|
||||||
selectedGroup={selectedGroup}
|
|
||||||
groupSection={groupSection}
|
|
||||||
isUnread={isUnread}
|
|
||||||
goToAnnouncements={goToAnnouncements}
|
|
||||||
isUnreadChat={isUnreadChat}
|
|
||||||
goToChat={goToChat}
|
|
||||||
goToThreads={goToThreads}
|
|
||||||
setOpenManageMembers={setOpenManageMembers}
|
|
||||||
groupChatHasUnread={groupChatHasUnread}
|
|
||||||
groupsAnnHasUnread={groupsAnnHasUnread}
|
|
||||||
directChatHasUnread={directChatHasUnread}
|
|
||||||
chatMode={chatMode}
|
|
||||||
openDrawerGroups={openDrawerGroups}
|
|
||||||
goToHome={goToHome}
|
|
||||||
setIsOpenDrawerProfile={setIsOpenDrawerProfile}
|
|
||||||
mobileViewMode={mobileViewMode}
|
|
||||||
setMobileViewMode={setMobileViewMode}
|
|
||||||
setMobileViewModeKeepOpen={setMobileViewModeKeepOpen}
|
|
||||||
hasUnreadGroups={groupChatHasUnread ||
|
|
||||||
groupsAnnHasUnread}
|
|
||||||
hasUnreadDirects={directChatHasUnread}
|
|
||||||
myName={userInfo?.name || null}
|
|
||||||
isHome={groupSection === "home" && desktopViewMode === 'home'}
|
|
||||||
isGroups={desktopSideView === 'groups' && desktopViewMode !== 'apps'}
|
|
||||||
isDirects={desktopSideView === 'directs' && desktopViewMode !== 'apps'}
|
|
||||||
setDesktopViewMode={setDesktopViewMode}
|
|
||||||
isApps={desktopViewMode === 'apps'}
|
|
||||||
setDesktopSideView={setDesktopSideView}
|
|
||||||
desktopViewMode={desktopViewMode}
|
|
||||||
hide={desktopViewMode === 'apps'}
|
|
||||||
setIsOpenSideViewDirects={setIsOpenSideViewDirects}
|
|
||||||
setIsOpenSideViewGroups={setIsOpenSideViewGroups}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{isMobile && mobileViewMode === "home" && (
|
{isMobile && mobileViewMode === "home" && (
|
||||||
<Home
|
<Home
|
||||||
refreshHomeDataFunc={refreshHomeDataFunc}
|
refreshHomeDataFunc={refreshHomeDataFunc}
|
||||||
@ -2848,20 +2791,20 @@ export const Group = ({
|
|||||||
setOpenManageMembers={setOpenManageMembers}
|
setOpenManageMembers={setOpenManageMembers}
|
||||||
setOpenAddGroup={setOpenAddGroup}
|
setOpenAddGroup={setOpenAddGroup}
|
||||||
setMobileViewMode={setMobileViewMode}
|
setMobileViewMode={setMobileViewMode}
|
||||||
|
setDesktopViewMode={setDesktopViewMode}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<Apps mode={appsMode} setMode={setAppsMode} show={mobileViewMode === "apps"} myName={userInfo?.name} />
|
<Apps mode={appsMode} setMode={setAppsMode} show={mobileViewMode === "apps"} myName={userInfo?.name} />
|
||||||
)}
|
)}
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<AppsDesktop toggleSideViewGroups={toggleSideViewGroups} toggleSideViewDirects={toggleSideViewDirects} goToHome={goToHome} mode={appsMode} setMode={setAppsMode} setDesktopSideView={setDesktopSideView} hasUnreadDirects={directChatHasUnread} show={desktopViewMode === "apps"} myName={userInfo?.name} isGroups={isOpenSideViewGroups}
|
<AppsDesktop toggleSideViewGroups={toggleSideViewGroups} toggleSideViewDirects={toggleSideViewDirects} goToHome={goToHome} mode={appsMode} setMode={setAppsMode} setDesktopSideView={setDesktopSideView} hasUnreadDirects={directChatHasUnread} show={desktopViewMode === "apps"} myName={userInfo?.name} isGroups={isOpenSideViewGroups}
|
||||||
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
|
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
|
||||||
groupsAnnHasUnread} />
|
groupsAnnHasUnread} setDesktopViewMode={setDesktopViewMode} isApps={desktopViewMode === 'apps'} desktopViewMode={desktopViewMode} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
{!isMobile && !selectedGroup &&
|
{!isMobile && desktopViewMode === 'home' && (
|
||||||
groupSection === "home" && desktopViewMode !== "apps" && (
|
|
||||||
<HomeDesktop
|
<HomeDesktop
|
||||||
refreshHomeDataFunc={refreshHomeDataFunc}
|
refreshHomeDataFunc={refreshHomeDataFunc}
|
||||||
myAddress={myAddress}
|
myAddress={myAddress}
|
||||||
@ -2875,6 +2818,8 @@ export const Group = ({
|
|||||||
setOpenManageMembers={setOpenManageMembers}
|
setOpenManageMembers={setOpenManageMembers}
|
||||||
setOpenAddGroup={setOpenAddGroup}
|
setOpenAddGroup={setOpenAddGroup}
|
||||||
setMobileViewMode={setMobileViewMode}
|
setMobileViewMode={setMobileViewMode}
|
||||||
|
setDesktopViewMode={setDesktopViewMode}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -2886,7 +2831,7 @@ export const Group = ({
|
|||||||
width: "31px",
|
width: "31px",
|
||||||
// minWidth: "135px",
|
// minWidth: "135px",
|
||||||
padding: "5px",
|
padding: "5px",
|
||||||
display: (isMobile || desktopViewMode === 'apps') ? "none" : "flex",
|
display: (isMobile || desktopViewMode === 'apps' || desktopViewMode === 'dev' || desktopViewMode === 'chat') ? "none" : "flex",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import { myGroupsWhereIAmAdminAtom } from "../../atoms/global";
|
|||||||
import { useSetRecoilState } from "recoil";
|
import { useSetRecoilState } from "recoil";
|
||||||
export const requestQueueGroupJoinRequests = new RequestQueueWithPromise(2)
|
export const requestQueueGroupJoinRequests = new RequestQueueWithPromise(2)
|
||||||
|
|
||||||
export const GroupJoinRequests = ({ myAddress, groups, setOpenManageMembers, getTimestampEnterChat, setSelectedGroup, setGroupSection, setMobileViewMode }) => {
|
export const GroupJoinRequests = ({ myAddress, groups, setOpenManageMembers, getTimestampEnterChat, setSelectedGroup, setGroupSection, setMobileViewMode, setDesktopViewMode }) => {
|
||||||
const [groupsWithJoinRequests, setGroupsWithJoinRequests] = React.useState([])
|
const [groupsWithJoinRequests, setGroupsWithJoinRequests] = React.useState([])
|
||||||
const [loading, setLoading] = React.useState(true)
|
const [loading, setLoading] = React.useState(true)
|
||||||
const {txList, setTxList} = React.useContext(MyContext)
|
const {txList, setTxList} = React.useContext(MyContext)
|
||||||
@ -185,6 +185,9 @@ export const GroupJoinRequests = ({ myAddress, groups, setOpenManageMembers, get
|
|||||||
getTimestampEnterChat()
|
getTimestampEnterChat()
|
||||||
setGroupSection("announcement")
|
setGroupSection("announcement")
|
||||||
setOpenManageMembers(true)
|
setOpenManageMembers(true)
|
||||||
|
if(!isMobile){
|
||||||
|
setDesktopViewMode('chat')
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
executeEvent("openGroupJoinRequest", {});
|
executeEvent("openGroupJoinRequest", {});
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ export const Home = ({
|
|||||||
setOpenManageMembers,
|
setOpenManageMembers,
|
||||||
setOpenAddGroup,
|
setOpenAddGroup,
|
||||||
setMobileViewMode,
|
setMobileViewMode,
|
||||||
|
setDesktopViewMode
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -97,6 +98,7 @@ export const Home = ({
|
|||||||
myAddress={myAddress}
|
myAddress={myAddress}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
setMobileViewMode={setMobileViewMode}
|
setMobileViewMode={setMobileViewMode}
|
||||||
|
setDesktopViewMode={setDesktopViewMode}
|
||||||
/>
|
/>
|
||||||
<GroupInvites
|
<GroupInvites
|
||||||
setOpenAddGroup={setOpenAddGroup}
|
setOpenAddGroup={setOpenAddGroup}
|
||||||
|
@ -21,6 +21,7 @@ export const HomeDesktop = ({
|
|||||||
setOpenManageMembers,
|
setOpenManageMembers,
|
||||||
setOpenAddGroup,
|
setOpenAddGroup,
|
||||||
setMobileViewMode,
|
setMobileViewMode,
|
||||||
|
setDesktopViewMode
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -67,7 +68,7 @@ export const HomeDesktop = ({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
gap: "15px",
|
gap: "15px",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
justifyContent: "flex-start",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
@ -106,6 +107,7 @@ export const HomeDesktop = ({
|
|||||||
myAddress={myAddress}
|
myAddress={myAddress}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
setMobileViewMode={setMobileViewMode}
|
setMobileViewMode={setMobileViewMode}
|
||||||
|
setDesktopViewMode={setDesktopViewMode}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
|
@ -57,6 +57,8 @@ useEffect(()=> {
|
|||||||
}, [])
|
}, [])
|
||||||
const showTutorial = useCallback(async (type, isForce) => {
|
const showTutorial = useCallback(async (type, isForce) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('type, isForce', type, isForce)
|
||||||
|
|
||||||
const isOnline = await checkIfGatewayIsOnline()
|
const isOnline = await checkIfGatewayIsOnline()
|
||||||
if(!isOnline) return
|
if(!isOnline) return
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -79,8 +79,8 @@ const hasExtension = (filename) => {
|
|||||||
return filename.includes(".") && filename.split(".").pop().length > 0;
|
return filename.includes(".") && filename.split(".").pop().length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createAccount = async()=> {
|
export const createAccount = async(generatedSeedPhrase)=> {
|
||||||
const generatedSeedPhrase = generateRandomSentence()
|
if(!generatedSeedPhrase) throw new Error('No generated seed-phrase')
|
||||||
const threads = doInitWorkers(crypto.kdfThreads)
|
const threads = doInitWorkers(crypto.kdfThreads)
|
||||||
|
|
||||||
const seed = await kdf(generatedSeedPhrase, void 0, threads)
|
const seed = await kdf(generatedSeedPhrase, void 0, threads)
|
||||||
@ -118,3 +118,12 @@ fileName = hasExtension(fileName) ? fileName : fileName + "." + fileExtension;
|
|||||||
await saveAs(blob, fileName);
|
await saveAs(blob, fileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const saveSeedPhraseToDisk = async (data) => {
|
||||||
|
|
||||||
|
const blob = new Blob([data], { type: 'text/plain;charset=utf-8' })
|
||||||
|
const fileName = "qortal_seedphrase.txt"
|
||||||
|
|
||||||
|
await saveAs(blob, fileName);
|
||||||
|
|
||||||
|
}
|
173
src/utils/seedPhrase/RandomSentenceGenerator.ts
Normal file
173
src/utils/seedPhrase/RandomSentenceGenerator.ts
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Author: irontiga <irontiga@gmail.com>
|
||||||
|
|
||||||
|
import { html, LitElement, css } from 'lit'
|
||||||
|
import * as WORDLISTS from './wordList'
|
||||||
|
|
||||||
|
class RandomSentenceGenerator extends LitElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
template: { type: String, attribute: 'template' },
|
||||||
|
parsedString: { type: String },
|
||||||
|
fetchedWordlistCount: { type: Number, value: 0 },
|
||||||
|
capitalize: { type: Boolean },
|
||||||
|
partsOfSpeechMap: { type: Object },
|
||||||
|
templateEntropy: { type: Number, reflect: true, attribute: 'template-entropy' },
|
||||||
|
maxWordLength: { type: Number, attribute: 'max-word-length' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.template = 'adjective noun verb adverb.'
|
||||||
|
this.maxWordLength = 0
|
||||||
|
this.parsedString = ''
|
||||||
|
this.fetchedWordlistCount = 0
|
||||||
|
this.capitalize = true
|
||||||
|
this.partsOfSpeechMap = {
|
||||||
|
'noun': 'nouns',
|
||||||
|
'adverb': 'adverbs',
|
||||||
|
'adv': 'adverbs',
|
||||||
|
'verb': 'verbs',
|
||||||
|
'interjection': 'interjections',
|
||||||
|
'adjective': 'adjectives',
|
||||||
|
'adj': 'adjectives',
|
||||||
|
'verbed': 'verbed'
|
||||||
|
}
|
||||||
|
this.partsOfSpeech = Object.keys(this.partsOfSpeechMap)
|
||||||
|
this._wordlists = WORDLISTS
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
div {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #1f2023;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div>${this.parsedString}</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
updated(changedProperties) {
|
||||||
|
let regen = false
|
||||||
|
|
||||||
|
if (changedProperties.has('template')) {
|
||||||
|
regen = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changedProperties.has('maxWordLength')) {
|
||||||
|
console.dir(this.maxWordLength)
|
||||||
|
|
||||||
|
if (this.maxWordLength) {
|
||||||
|
const wl = { ...this._wordlists }
|
||||||
|
|
||||||
|
for (const partOfSpeech in this._wordlists) {
|
||||||
|
if (Array.isArray(this._wordlists[partOfSpeech])) {
|
||||||
|
wl[partOfSpeech] = this._wordlists[partOfSpeech].filter(word => word.length <= this.maxWordLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._wordlists = wl
|
||||||
|
}
|
||||||
|
|
||||||
|
regen = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regen) this.generate()
|
||||||
|
}
|
||||||
|
|
||||||
|
_RNG(entropy) {
|
||||||
|
if (entropy > 1074) {
|
||||||
|
throw new Error('Javascript can not handle that much entropy!')
|
||||||
|
}
|
||||||
|
|
||||||
|
let randNum = 0
|
||||||
|
|
||||||
|
const crypto = window.crypto || window.msCrypto
|
||||||
|
|
||||||
|
if (crypto) {
|
||||||
|
const entropy256 = Math.ceil(entropy / 8)
|
||||||
|
|
||||||
|
let buffer = new Uint8Array(entropy256)
|
||||||
|
|
||||||
|
crypto.getRandomValues(buffer)
|
||||||
|
|
||||||
|
randNum = buffer.reduce((num, value) => {
|
||||||
|
return num * value
|
||||||
|
}, 1) / Math.pow(256, entropy256)
|
||||||
|
} else {
|
||||||
|
console.warn('Secure RNG not found. Using Math.random')
|
||||||
|
|
||||||
|
randNum = Math.random()
|
||||||
|
}
|
||||||
|
|
||||||
|
return randNum
|
||||||
|
}
|
||||||
|
|
||||||
|
setRNG(fn) {
|
||||||
|
this._RNG = fn
|
||||||
|
}
|
||||||
|
|
||||||
|
_captitalize(str) {
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
getWord(partOfSpeech) {
|
||||||
|
const words = this._wordlists[this.partsOfSpeechMap[partOfSpeech]]
|
||||||
|
const requiredEntropy = Math.log(words.length) / Math.log(2)
|
||||||
|
const index = this._RNG(requiredEntropy) * words.length
|
||||||
|
|
||||||
|
return {
|
||||||
|
word: words[Math.round(index)],
|
||||||
|
entropy: words.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate() {
|
||||||
|
this.parsedString = this.parse(this.template)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(template) {
|
||||||
|
const split = template.split(/[\s]/g)
|
||||||
|
|
||||||
|
let entropy = 1
|
||||||
|
|
||||||
|
const final = split.map(word => {
|
||||||
|
const lower = word.toLowerCase()
|
||||||
|
|
||||||
|
this.partsOfSpeech.some(partOfSpeech => {
|
||||||
|
const partOfSpeechIndex = lower.indexOf(partOfSpeech) // Check it exists
|
||||||
|
const nextChar = word.charAt(partOfSpeech.length)
|
||||||
|
|
||||||
|
if (partOfSpeechIndex === 0 && !(nextChar && (nextChar.match(/[a-zA-Z]/g) != null))) {
|
||||||
|
const replacement = this.getWord(partOfSpeech)
|
||||||
|
word = replacement.word + word.slice(partOfSpeech.length) // Append the rest of the "word" (punctuation)
|
||||||
|
entropy = entropy * replacement.entropy
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return word
|
||||||
|
})
|
||||||
|
|
||||||
|
this.templateEntropy = Math.floor(Math.log(entropy) / Math.log(8))
|
||||||
|
|
||||||
|
return final.join(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('random-sentence-generator', RandomSentenceGenerator)
|
||||||
|
|
||||||
|
export default RandomSentenceGenerator
|
40
src/utils/seedPhrase/verb-past-tense.ts
Normal file
40
src/utils/seedPhrase/verb-past-tense.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
export const EXCEPTIONS = {
|
||||||
|
'are': 'were',
|
||||||
|
'eat': 'ate',
|
||||||
|
'go': 'went',
|
||||||
|
'have': 'had',
|
||||||
|
'inherit': 'inherited',
|
||||||
|
'is': 'was',
|
||||||
|
'run': 'ran',
|
||||||
|
'sit': 'sat',
|
||||||
|
'visit': 'visited'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getPastTense = (verb, exceptions = EXCEPTIONS) => {
|
||||||
|
if (exceptions[verb]) {
|
||||||
|
return exceptions[verb]
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((/e$/i).test(verb)) {
|
||||||
|
return verb + 'd'
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((/[aeiou]c$/i).test(verb)) {
|
||||||
|
return verb + 'ked'
|
||||||
|
}
|
||||||
|
|
||||||
|
// for american english only
|
||||||
|
if ((/el$/i).test(verb)) {
|
||||||
|
return verb + 'ed'
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((/[aeio][aeiou][dlmnprst]$/).test(verb)) {
|
||||||
|
return verb + 'ed'
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((/[aeiou][bdglmnprst]$/i).test(verb)) {
|
||||||
|
return verb.replace(/(.+[aeiou])([bdglmnprst])/, '$1$2$2ed')
|
||||||
|
}
|
||||||
|
|
||||||
|
return verb + 'ed'
|
||||||
|
}
|
32
src/utils/seedPhrase/wordList.ts
Normal file
32
src/utils/seedPhrase/wordList.ts
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user