diff --git a/src/App.tsx b/src/App.tsx index eaa3f17..37a8954 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,6 +20,7 @@ import { DialogContent, DialogContentText, DialogTitle, + Divider, Input, InputLabel, Popover, @@ -27,6 +28,8 @@ import { Typography, } from "@mui/material"; import { decryptStoredWallet } from "./utils/decryptWallet"; +import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'; + import { JsonView, allExpanded, darkStyles } from 'react-json-view-lite'; import 'react-json-view-lite/dist/index.css'; import { CountdownCircleTimer } from "react-countdown-circle-timer"; @@ -1659,7 +1662,7 @@ function App() { REGISTER NAME )} - + {/* */} { setIsOpenSendQort(true); @@ -1669,14 +1672,46 @@ function App() { > Transfer QORT + + { + setIsOpenDrawerProfile(false); + executeEvent("openWalletsApp", { + + }); + }} + > + + + See Wallets + + + + )} + { + const [open, setOpen] = useState(false); return ( - - - Your address - - + + { + setOpen((prev)=> !prev); + }} + > + {open ? 'Hide QR code' :'See QR code'} + + + {open && ( + + + + Your address + + + + + )} ); }; diff --git a/src/components/Apps/AppViewer.tsx b/src/components/Apps/AppViewer.tsx index 902c6d8..cd9cf94 100644 --- a/src/components/Apps/AppViewer.tsx +++ b/src/components/Apps/AppViewer.tsx @@ -11,11 +11,11 @@ import { useQortalMessageListener } from "./useQortalMessageListener"; -export const AppViewer = React.forwardRef(({ app , hide, isDevMode}, iframeRef) => { +export const AppViewer = React.forwardRef(({ app , hide, isDevMode, skipAuth}, iframeRef) => { const { rootHeight } = useContext(MyContext); // const iframeRef = useRef(null); const { document, window: frameWindow } = useFrame(); - const {path, history, changeCurrentIndex, resetHistory} = useQortalMessageListener(frameWindow, iframeRef, app?.tabId, isDevMode, app?.name, app?.service) + const {path, history, changeCurrentIndex, resetHistory} = useQortalMessageListener(frameWindow, iframeRef, app?.tabId, isDevMode, app?.name, app?.service, skipAuth) const [url, setUrl] = useState('') diff --git a/src/components/Apps/AppViewerContainer.tsx b/src/components/Apps/AppViewerContainer.tsx index 2182286..9eea56d 100644 --- a/src/components/Apps/AppViewerContainer.tsx +++ b/src/components/Apps/AppViewerContainer.tsx @@ -3,7 +3,7 @@ import { AppViewer } from './AppViewer'; import Frame from 'react-frame-component'; import { MyContext, isMobile } from '../../App'; -const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, customHeight, isDevMode }, ref) => { +const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, customHeight, isDevMode, skipAuth }, ref) => { const { rootHeight } = useContext(MyContext); @@ -42,7 +42,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, customHeig overflow: 'hidden', }} > - + ); }); diff --git a/src/components/Apps/AppsCategory.tsx b/src/components/Apps/AppsCategory.tsx index b3aff55..be2fa1a 100644 --- a/src/components/Apps/AppsCategory.tsx +++ b/src/components/Apps/AppsCategory.tsx @@ -40,7 +40,8 @@ const officialAppList = [ "q-shop", "q-trade", "q-support", - "q-manager" + "q-manager", + "q-wallets" ]; const ScrollerStyled = styled('div')({ diff --git a/src/components/Apps/AppsCategoryDesktop.tsx b/src/components/Apps/AppsCategoryDesktop.tsx index 63e535c..3844907 100644 --- a/src/components/Apps/AppsCategoryDesktop.tsx +++ b/src/components/Apps/AppsCategoryDesktop.tsx @@ -46,7 +46,8 @@ const officialAppList = [ "q-mail", "q-fund", "q-shop", - "q-manager" + "q-manager", + "q-wallets" ]; const ScrollerStyled = styled("div")({ diff --git a/src/components/Apps/AppsLibrary.tsx b/src/components/Apps/AppsLibrary.tsx index 9365263..1650e28 100644 --- a/src/components/Apps/AppsLibrary.tsx +++ b/src/components/Apps/AppsLibrary.tsx @@ -44,7 +44,8 @@ const officialAppList = [ "q-trade", "q-support", "q-manager", - "q-mintership" + "q-mintership", + "q-wallets" ]; const ScrollerStyled = styled('div')({ diff --git a/src/components/Apps/AppsLibraryDesktop.tsx b/src/components/Apps/AppsLibraryDesktop.tsx index 6cf511d..d2255e1 100644 --- a/src/components/Apps/AppsLibraryDesktop.tsx +++ b/src/components/Apps/AppsLibraryDesktop.tsx @@ -55,7 +55,8 @@ const officialAppList = [ "q-fund", "q-shop", "q-manager", - "q-mintership" + "q-mintership", + "q-wallets" ]; const ScrollerStyled = styled("div")({ diff --git a/src/components/Apps/useQortalMessageListener.tsx b/src/components/Apps/useQortalMessageListener.tsx index 249ccec..672b1ae 100644 --- a/src/components/Apps/useQortalMessageListener.tsx +++ b/src/components/Apps/useQortalMessageListener.tsx @@ -486,7 +486,7 @@ const UIQortalRequests = [ return obj; // Updated object with references to stored files } -export const useQortalMessageListener = (frameWindow, iframeRef, tabId, appName, appService) => { +export const useQortalMessageListener = (frameWindow, iframeRef, tabId, isDevMode, appName, appService, skipAuth) => { const [path, setPath] = useState('') const [history, setHistory] = useState({ customQDNHistoryPaths: [], @@ -542,7 +542,7 @@ isDOMContentLoaded: false const sendMessageToRuntime = (message, eventPort) => { window.sendMessage(message.action, message.payload, 300000, message.isExtension, { name: appName, service: appService - }) + }, skipAuth) .then((response) => { if (response.error) { eventPort.postMessage({ @@ -636,7 +636,9 @@ isDOMContentLoaded: false window.sendMessage("addEnteredQmailTimestamp").catch((error) => { // error }); - } + } else if(appName?.toLowerCase() === 'q-wallets'){ + executeEvent('setLastEnteredTimestampPaymentEvent', {}) + } } else if(event?.data?.action === 'NAVIGATION_HISTORY'){ if(event?.data?.payload?.isDOMContentLoaded){ setHistory((prev)=> { diff --git a/src/components/Explore/Explore.tsx b/src/components/Explore/Explore.tsx index c8d7789..aad85c9 100644 --- a/src/components/Explore/Explore.tsx +++ b/src/components/Explore/Explore.tsx @@ -4,6 +4,9 @@ import ChatIcon from "@mui/icons-material/Chat"; import qTradeLogo from "../../assets/Icons/q-trade-logo.webp"; import AppsIcon from "@mui/icons-material/Apps"; import { executeEvent } from "../../utils/events"; +import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'; + + export const Explore = ({setMobileViewMode}) => { return ( { display: "flex", gap: "20px", flexWrap: "wrap", - justifyContent: 'center' + justifyContent: 'center', + padding: '10px' }} > { General Chat + { + executeEvent("openWalletsApp", { + + }); + }} + > + + + Wallets + + ); }; diff --git a/src/components/GlobalTouchMenu.tsx b/src/components/GlobalTouchMenu.tsx index 6de2ae9..48e5128 100644 --- a/src/components/GlobalTouchMenu.tsx +++ b/src/components/GlobalTouchMenu.tsx @@ -109,7 +109,13 @@ export const GlobalTouchMenu = () => { executeEvent('openUserProfile',{}) handleClose() }}> - Wallet + My Account + + { + executeEvent('openWalletsApp', {}) + handleClose() + }}> + Wallets ); diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index c68e46e..44bdd68 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -20,6 +20,7 @@ import React, { useState, } from "react"; import BlockIcon from '@mui/icons-material/Block'; +import { WalletsAppWrapper } from "./WalletsAppWrapper"; import SettingsIcon from "@mui/icons-material/Settings"; import { ChatGroup } from "../Chat/ChatGroup"; @@ -2226,7 +2227,9 @@ export const Group = ({ setNewChat={setNewChat} /> )} - + + +
{ + const iframeRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + const [navigationController, setNavigationController] = useRecoilState( + navigationControllerAtom + ); + const [selectedTab, setSelectedTab] = useState({ + tabId: "5558589", + name: "Q-Wallets", + service: "APP", + path: '/qortal' + }); + + const isDisableBackButton = useMemo(() => { + if (selectedTab && navigationController[selectedTab?.tabId]?.hasBack) + return false; + if (selectedTab && !navigationController[selectedTab?.tabId]?.hasBack) + return true; + return false; + }, [navigationController, selectedTab]); + + const openWalletsAppFunc = useCallback( + (e) => { + setIsOpen(true); + }, + [setIsOpen] + ); + + useEffect(() => { + subscribeToEvent("openWalletsApp", openWalletsAppFunc); + + return () => { + unsubscribeFromEvent("openWalletsApp", openWalletsAppFunc); + }; + }, [openWalletsAppFunc]); + + const handleClose = ()=> { + setIsOpen(false); + iframeRef.current = null + } + + return ( + <> + {isOpen && ( + + + + Q-Wallets + + + + + + + + + { + executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {}); + }} + disabled={isDisableBackButton} + sx={{ + opacity: !isDisableBackButton ? 1 : 0.1, + cursor: !isDisableBackButton ? "pointer" : "default", + }} + > + + + { + if (selectedTab?.refreshFunc) { + selectedTab.refreshFunc(selectedTab?.tabId); + + } else { + executeEvent("refreshApp", { + tabId: selectedTab?.tabId, + }); + } + + + }}> + + + + + + + )} + + ); +}; diff --git a/src/components/Mobile/MobileHeader.tsx b/src/components/Mobile/MobileHeader.tsx index d25b84b..e224bd0 100644 --- a/src/components/Mobile/MobileHeader.tsx +++ b/src/components/Mobile/MobileHeader.tsx @@ -28,6 +28,7 @@ import { useAppFullScreen } from "../../useAppFullscreen"; import { useHandlePaymentNotification } from "../../hooks/useHandlePaymentNotification"; import { formatDate } from "../../utils/time"; import AccountBalanceWalletIcon from "@mui/icons-material/AccountBalanceWallet"; +import { executeEvent } from "../../utils/events"; const Header = ({ logoutFunc, @@ -545,12 +546,12 @@ const Header = ({ width: "100%", alignItems: "flex-start", textWrap: "auto", - cursor: 'default' - }} - onClick={(e) => { - // executeEvent("addTab", { data: { service: 'APP', name: 'q-mail' } }); - // executeEvent("open-apps-mode", { }); }} + onClick={() => { + + executeEvent('openWalletsApp', {}) + handleClose() + }} > { const [latestTx, setLatestTx] = useState(null); @@ -106,6 +107,21 @@ export const useHandlePaymentNotification = (address) => { window.removeEventListener("message", messageHandler); }; }, [getLastSeenData]); + + const setLastEnteredTimestampPaymentEventFunc = useCallback( + (e) => { + setLastEnteredTimestampPayment(Date.now) + }, + [setLastEnteredTimestampPayment] + ); + + useEffect(() => { + subscribeToEvent("setLastEnteredTimestampPaymentEvent", setLastEnteredTimestampPaymentEventFunc); + + return () => { + unsubscribeFromEvent("setLastEnteredTimestampPaymentEvent", setLastEnteredTimestampPaymentEventFunc); + }; + }, [setLastEnteredTimestampPaymentEventFunc]); return { latestTx, getNameOrAddressOfSenderMiddle, diff --git a/src/messaging/messagesToBackground.tsx b/src/messaging/messagesToBackground.tsx index 4ad3812..1304b41 100644 --- a/src/messaging/messagesToBackground.tsx +++ b/src/messaging/messagesToBackground.tsx @@ -24,14 +24,14 @@ window.addEventListener("message", (event) => { } }); -export const sendMessageBackground = (action, data = {}, timeout = 180000, isExtension, appInfo) => { +export const sendMessageBackground = (action, data = {}, timeout = 180000, isExtension, appInfo, skipAuth) => { return new Promise((resolve, reject) => { const requestId = generateRequestId(); // Unique ID for each request callbackMap.set(requestId, { resolve, reject }); // Store both resolve and reject callbacks const targetOrigin = window.location.origin // Send the message with `backgroundMessage` type - window.postMessage({ type: "backgroundMessage", action, requestId, payload: data, isExtension, appInfo }, targetOrigin); + window.postMessage({ type: "backgroundMessage", action, requestId, payload: data, isExtension, appInfo, skipAuth }, targetOrigin); // Set up a timeout to automatically reject if no response is received const timeoutId = setTimeout(() => { diff --git a/src/qortalRequests.ts b/src/qortalRequests.ts index 116a50a..ba5d476 100644 --- a/src/qortalRequests.ts +++ b/src/qortalRequests.ts @@ -71,6 +71,7 @@ export const isRunningGateway = async ()=> { // Ensure the message is from a trusted source const isFromExtension = request?.isExtension; const appInfo = request?.appInfo; + const skipAuth = request?.skipAuth || false if (request?.type !== "backgroundMessage") return; // Only process messages of type 'backgroundMessage' @@ -78,7 +79,7 @@ export const isRunningGateway = async ()=> { switch (request.action) { case "GET_USER_ACCOUNT": { try { - const res = await getUserAccount({isFromExtension, appInfo}); + const res = await getUserAccount({isFromExtension, appInfo, skipAuth}); event.source.postMessage({ requestId: request.requestId, action: request.action, diff --git a/src/qortalRequests/get.ts b/src/qortalRequests/get.ts index c7e4cf7..2cadaaa 100644 --- a/src/qortalRequests/get.ts +++ b/src/qortalRequests/get.ts @@ -354,13 +354,16 @@ async function getUserPermission(payload, isFromExtension) { } -export const getUserAccount = async ({isFromExtension, appInfo}) => { +export const getUserAccount = async ({isFromExtension, appInfo, skipAuth}) => { try { const value = (await getPermission(`qAPPAutoAuth-${appInfo?.name}`)) || false; let skip = false; if (value) { skip = true; } + if(skipAuth){ + skip = true + } let resPermission if(!skip){ resPermission = await getUserPermission({