added wallets embed

This commit is contained in:
PhilReact 2025-03-08 20:09:59 +02:00
parent 857f2980b7
commit 1894fb7756
15 changed files with 294 additions and 25 deletions

View File

@ -52,7 +52,7 @@ import EngineeringIcon from '@mui/icons-material/Engineering';
import WarningIcon from '@mui/icons-material/Warning';
import { DrawerUserLookup } from "./components/Drawer/DrawerUserLookup";
import { UserLookup } from "./components/UserLookup.tsx/UserLookup";
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
import {
createAccount,
generateRandomSentence,
@ -1756,12 +1756,45 @@ function App() {
/>
</Tooltip>
</ButtonBase>
<Spacer height="20px" />
<ButtonBase
onClick={() => {
executeEvent('openWalletsApp', {})
}}
>
<Tooltip
title={<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}>WALLETS</span>}
placement="left"
arrow
sx={{ fontSize: "24" }}
slotProps={{
tooltip: {
sx: {
color: "#ffffff",
backgroundColor: "#444444",
},
},
arrow: {
sx: {
color: "#444444",
},
},
}}
>
<AccountBalanceWalletIcon
sx={{
color: "rgba(255, 255, 255, 0.5)",
}}
/>
</Tooltip>
</ButtonBase>
{desktopViewMode !== 'home' && (
<>
<Spacer height="20px" />
<Tooltip
title={<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}>WALLET</span>}
title={<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}>YOUR ACCOUNT</span>}
placement="left"
arrow
sx={{ fontSize: "24" }}

View File

@ -33,6 +33,10 @@ export const sortablePinnedAppsAtom = atom({
{
name: 'Q-Mintership',
service: 'APP'
},
{
name: 'Q-Wallets',
service: 'APP'
}
],
});

View File

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

View File

@ -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, isDevMode, customHeight }, ref) => {
const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode, customHeight, skipAuth }, ref) => {
const { rootHeight } = useContext(MyContext);
@ -42,7 +42,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode,
overflow: 'hidden',
}}
>
<AppViewer app={app} ref={ref} hide={!isSelected || hide} isDevMode={isDevMode} />
<AppViewer app={app} ref={ref} hide={!isSelected || hide} isDevMode={isDevMode} skipAuth={skipAuth} />
</Frame>
);
});

View File

@ -43,6 +43,7 @@ const officialAppList = [
"q-shop",
"q-trade",
"q-support",
"q-wallets"
];
const ScrollerStyled = styled('div')({

View File

@ -59,7 +59,8 @@ const officialAppList = [
"q-trade",
"q-support",
"q-mintership",
"q-manager"
"q-manager",
"q-wallets"
];
const ScrollerStyled = styled("div")({

View File

@ -424,7 +424,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: [],
@ -530,7 +530,7 @@ isDOMContentLoaded: false
sendMessageToRuntime(
{ action: event.data.action, type: 'qortalRequest', payload: event.data, isExtension: true, appInfo: {
name: appName, service: appService
} },
}, skipAuth },
event.ports[0]
);
} else if (
@ -578,7 +578,9 @@ isDOMContentLoaded: false
// response
}
);
}
} else if(appName?.toLowerCase() === 'q-wallets'){
executeEvent('setLastEnteredTimestampPaymentEvent', {})
}
} else if(event?.data?.action === 'NAVIGATION_HISTORY'){
if(event?.data?.payload?.isDOMContentLoaded){
setHistory((prev)=> {

View File

@ -160,7 +160,6 @@ export const useBlockedAddresses = () => {
},
},
(response) => {
console.log('response', response)
if (response.error) {
rej(response?.message);
return;

View File

@ -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 = ({setDesktopViewMode}) => {
return (
<Box
@ -96,6 +99,33 @@ export const Explore = ({setDesktopViewMode}) => {
General Chat
</Typography>
</ButtonBase>
<ButtonBase
sx={{
"&:hover": { backgroundColor: "secondary.main" },
transition: "all 0.1s ease-in-out",
padding: "5px",
borderRadius: "5px",
gap: "5px",
}}
onClick={async () => {
executeEvent("openWalletsApp", {
});
}}
>
<AccountBalanceWalletIcon
sx={{
color: "white",
}}
/>
<Typography
sx={{
fontSize: "1rem",
}}
>
Wallets
</Typography>
</ButtonBase>
</Box>
);
};

View File

@ -13,6 +13,7 @@ import NotificationsIcon from "@mui/icons-material/Notifications";
import AccountBalanceWalletIcon from "@mui/icons-material/AccountBalanceWallet";
import { formatDate } from "../utils/time";
import { useHandlePaymentNotification } from "../hooks/useHandlePaymentNotification";
import { executeEvent } from "../utils/events";
export const GeneralNotifications = ({ address }) => {
const [anchorEl, setAnchorEl] = useState(null);
@ -35,11 +36,31 @@ export const GeneralNotifications = ({ address }) => {
}}
style={{}}
>
<Tooltip
title={<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}>PAYMENT NOTIFICATION</span>}
placement="left"
arrow
sx={{ fontSize: "24" }}
slotProps={{
tooltip: {
sx: {
color: "#ffffff",
backgroundColor: "#444444",
},
},
arrow: {
sx: {
color: "#444444",
},
},
}}
>
<NotificationsIcon
sx={{
color: hasNewPayment ? "var(--unread)" : "rgba(255, 255, 255, 0.5)",
}}
/>
</Tooltip>
</ButtonBase>
<Popover
@ -77,12 +98,11 @@ export const GeneralNotifications = ({ address }) => {
width: "100%",
alignItems: "flex-start",
textWrap: "auto",
cursor: 'default'
}}
onClick={(e) => {
// executeEvent("addTab", { data: { service: 'APP', name: 'q-mail' } });
// executeEvent("open-apps-mode", { });
}}
onClick={() => {
setAnchorEl(null)
executeEvent('openWalletsApp', {})
}}
>
<Card sx={{
padding: '10px',

View File

@ -103,6 +103,7 @@ import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import { DesktopSideBar } from "../DesktopSideBar";
import BlockIcon from '@mui/icons-material/Block';
import { BlockedUsersModal } from "./BlockedUsersModal";
import { WalletsAppWrapper } from "./WalletsAppWrapper";
// let touchStartY = 0;
@ -2845,7 +2846,8 @@ export const Group = ({
groupsAnnHasUnread} setDesktopViewMode={setDesktopViewMode} isApps={desktopViewMode === 'apps'} desktopViewMode={desktopViewMode} />
)}
<WalletsAppWrapper />
{!isMobile && (
<HomeDesktop

View File

@ -0,0 +1,163 @@
import { Box, ButtonBase, Divider, Typography } from "@mui/material";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import CloseIcon from "@mui/icons-material/Close";
import AppViewerContainer from "../Apps/AppViewerContainer";
import {
executeEvent,
subscribeToEvent,
unsubscribeFromEvent,
} from "../../utils/events";
import { useRecoilState } from "recoil";
import { navigationControllerAtom } from "../../atoms/global";
import { AppsNavBarLeft, AppsNavBarParent } from "../Apps/Apps-styles";
import NavBack from "../../assets/svgs/NavBack.svg";
import RefreshIcon from "@mui/icons-material/Refresh";
export const WalletsAppWrapper = () => {
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 && (
<Box
sx={{
position: "fixed",
height: "1000px",
maxHeight: "100vh",
width: "1200px",
maxWidth: "100vw",
backgroundColor: "#27282c",
zIndex: 100,
bottom: 0,
right: 0,
overflow: "hidden",
borderTopLeftRadius: "10px",
borderTopRightRadius: "10px",
boxShadow: 4,
}}
>
<Box
sx={{
height: "100%",
width: "100%",
}}
>
<Box
sx={{
height: "40px",
display: "flex",
alignItems: "center",
padding: "5px",
justifyContent: "space-between",
}}
>
<Typography>Q-Wallets</Typography>
<ButtonBase
onClick={handleClose}
>
<CloseIcon
sx={{
color: "white",
}}
/>
</ButtonBase>
</Box>
<Divider />
<AppViewerContainer
customHeight="calc(100% - 40px - 60px)"
app={selectedTab}
isSelected
ref={iframeRef}
skipAuth={true}
/>
<AppsNavBarParent>
<AppsNavBarLeft sx={{
gap: '25px'
}}>
<ButtonBase
onClick={() => {
executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {});
}}
disabled={isDisableBackButton}
sx={{
opacity: !isDisableBackButton ? 1 : 0.1,
cursor: !isDisableBackButton ? "pointer" : "default",
}}
>
<img src={NavBack} />
</ButtonBase>
<ButtonBase onClick={() => {
if (selectedTab?.refreshFunc) {
selectedTab.refreshFunc(selectedTab?.tabId);
} else {
executeEvent("refreshApp", {
tabId: selectedTab?.tabId,
});
}
}}>
<RefreshIcon
height={20}
sx={{
color: "rgba(250, 250, 250, 0.5)",
height: '30px',
width: 'auto'
}}
/>
</ButtonBase>
</AppsNavBarLeft>
</AppsNavBarParent>
</Box>
</Box>
)}
</>
);
};

View File

@ -3,6 +3,7 @@ import { getBaseApiReact } from '../App';
import { addTimestampLatestPayment, checkDifference, getNameInfoForOthers, getTimestampLatestPayment } from '../background';
import { useRecoilState } from 'recoil';
import { lastPaymentSeenTimestampAtom } from '../atoms/global';
import { subscribeToEvent, unsubscribeFromEvent } from '../utils/events';
export const useHandlePaymentNotification = (address) => {
const [latestTx, setLatestTx] = useState(null);
@ -54,16 +55,12 @@ export const useHandlePaymentNotification = (address) => {
return false;
}, [lastEnteredTimestampPayment, latestTx]);
console.log('hasNewPayment', hasNewPayment)
const getLastSeenData = useCallback(async () => {
try {
if (!address) return;
console.log('address', address)
const key = `last-seen-payment-${address}`;
const res = await getTimestampLatestPayment<any>().catch(() => null);
console.log('res', res)
if (res) {
setLastEnteredTimestampPayment(res);
}
@ -73,7 +70,6 @@ export const useHandlePaymentNotification = (address) => {
);
const responseData = await response.json();
console.log('responseData', responseData)
const latestTx = responseData.filter(
(tx) => tx?.creatorAddress !== address && tx?.recipient === address
)[0];
@ -92,12 +88,26 @@ export const useHandlePaymentNotification = (address) => {
getLastSeenData();
chrome?.runtime?.onMessage.addListener((message, sender, sendResponse) => {
console.log('message', message)
if (message?.action === "SET_PAYMENT_ANNOUNCEMENT" && message?.payload) {
setLatestTx(message.payload);
}
});
}, [getLastSeenData]);
const setLastEnteredTimestampPaymentEventFunc = useCallback(
(e) => {
setLastEnteredTimestampPayment(Date.now)
},
[setLastEnteredTimestampPayment]
);
useEffect(() => {
subscribeToEvent("setLastEnteredTimestampPaymentEvent", setLastEnteredTimestampPaymentEventFunc);
return () => {
unsubscribeFromEvent("setLastEnteredTimestampPaymentEvent", setLastEnteredTimestampPaymentEventFunc);
};
}, [setLastEnteredTimestampPaymentEventFunc]);
return {
latestTx,
getNameOrAddressOfSenderMiddle,

View File

@ -155,9 +155,10 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
if (request) {
const isFromExtension = request?.isExtension
const appInfo = request?.appInfo;
const skipAuth = request?.skipAuth
switch (request.action) {
case "GET_USER_ACCOUNT": {
getUserAccount({isFromExtension, appInfo})
getUserAccount({isFromExtension, appInfo, skipAuth})
.then((res) => {
sendResponse(res);
})

View File

@ -545,13 +545,16 @@ async function getUserPermission(payload: any, isFromExtension?: boolean) {
});
}
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({