mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-23 19:37:52 +00:00
added payment notification
This commit is contained in:
parent
91f787c18a
commit
548ba9b29c
@ -120,6 +120,7 @@ import {
|
|||||||
hasSettingsChangedAtom,
|
hasSettingsChangedAtom,
|
||||||
isDisabledEditorEnterAtom,
|
isDisabledEditorEnterAtom,
|
||||||
isUsingImportExportSettingsAtom,
|
isUsingImportExportSettingsAtom,
|
||||||
|
lastPaymentSeenTimestampAtom,
|
||||||
mailsAtom,
|
mailsAtom,
|
||||||
oldPinnedAppsAtom,
|
oldPinnedAppsAtom,
|
||||||
qMailLastEnteredTimestampAtom,
|
qMailLastEnteredTimestampAtom,
|
||||||
@ -154,6 +155,7 @@ import { UserLookup } from "./components/UserLookup.tsx/UserLookup";
|
|||||||
import { RegisterName } from "./components/RegisterName";
|
import { RegisterName } from "./components/RegisterName";
|
||||||
import { BuyQortInformation } from "./components/BuyQortInformation";
|
import { BuyQortInformation } from "./components/BuyQortInformation";
|
||||||
import { QortPayment } from "./components/QortPayment";
|
import { QortPayment } from "./components/QortPayment";
|
||||||
|
import { GeneralNotifications } from "./components/GeneralNotifications";
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
| "not-authenticated"
|
| "not-authenticated"
|
||||||
@ -508,6 +510,7 @@ function App() {
|
|||||||
const resetAtomQMailLastEnteredTimestampAtom = useResetRecoilState(qMailLastEnteredTimestampAtom)
|
const resetAtomQMailLastEnteredTimestampAtom = useResetRecoilState(qMailLastEnteredTimestampAtom)
|
||||||
const resetAtomMailsAtom = useResetRecoilState(mailsAtom)
|
const resetAtomMailsAtom = useResetRecoilState(mailsAtom)
|
||||||
const resetGroupPropertiesAtom = useResetRecoilState(groupsPropertiesAtom)
|
const resetGroupPropertiesAtom = useResetRecoilState(groupsPropertiesAtom)
|
||||||
|
const resetLastPaymentSeenTimestampAtom = useResetRecoilState(lastPaymentSeenTimestampAtom)
|
||||||
const resetAllRecoil = () => {
|
const resetAllRecoil = () => {
|
||||||
resetAtomSortablePinnedAppsAtom();
|
resetAtomSortablePinnedAppsAtom();
|
||||||
resetAtomCanSaveSettingToQdnAtom();
|
resetAtomCanSaveSettingToQdnAtom();
|
||||||
@ -518,6 +521,7 @@ function App() {
|
|||||||
resetAtomQMailLastEnteredTimestampAtom()
|
resetAtomQMailLastEnteredTimestampAtom()
|
||||||
resetAtomMailsAtom()
|
resetAtomMailsAtom()
|
||||||
resetGroupPropertiesAtom()
|
resetGroupPropertiesAtom()
|
||||||
|
resetLastPaymentSeenTimestampAtom()
|
||||||
|
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -1802,6 +1806,11 @@ function App() {
|
|||||||
<CoreSyncStatus />
|
<CoreSyncStatus />
|
||||||
<Spacer height="20px" />
|
<Spacer height="20px" />
|
||||||
<QMailStatus />
|
<QMailStatus />
|
||||||
|
<Spacer height="20px"/>
|
||||||
|
{extState === 'authenticated' && (
|
||||||
|
<GeneralNotifications address={userInfo?.address} />
|
||||||
|
)}
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -156,6 +156,11 @@ export const qMailLastEnteredTimestampAtom = atom({
|
|||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const lastPaymentSeenTimestampAtom = atom<null | number>({
|
||||||
|
key: 'lastPaymentSeenTimestampAtom',
|
||||||
|
default: null,
|
||||||
|
});
|
||||||
|
|
||||||
export const mailsAtom = atom({
|
export const mailsAtom = atom({
|
||||||
key: 'mailsAtom',
|
key: 'mailsAtom',
|
||||||
default: [],
|
default: [],
|
||||||
|
@ -262,11 +262,12 @@ export const getForeignKey = async (foreignBlockchain)=> {
|
|||||||
|
|
||||||
export const pauseAllQueues = () => controlAllQueues("pause");
|
export const pauseAllQueues = () => controlAllQueues("pause");
|
||||||
export const resumeAllQueues = () => controlAllQueues("resume");
|
export const resumeAllQueues = () => controlAllQueues("resume");
|
||||||
const checkDifference = (createdTimestamp) => {
|
export const checkDifference = (createdTimestamp, diff = timeDifferenceForNotificationChatsBackground) => {
|
||||||
return (
|
return (
|
||||||
Date.now() - createdTimestamp < timeDifferenceForNotificationChatsBackground
|
Date.now() - createdTimestamp < diff
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getApiKeyFromStorage = async (): Promise<string | null> => {
|
export const getApiKeyFromStorage = async (): Promise<string | null> => {
|
||||||
return getData<string>("apiKey").catch(() => null);
|
return getData<string>("apiKey").catch(() => null);
|
||||||
};
|
};
|
||||||
@ -518,6 +519,7 @@ const handleNotificationDirect = async (directs) => {
|
|||||||
`_from=${newestLatestTimestamp.address}`);
|
`_from=${newestLatestTimestamp.address}`);
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -559,6 +561,7 @@ const handleNotificationDirect = async (directs) => {
|
|||||||
|
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -746,6 +749,7 @@ const handleNotification = async (groups) => {
|
|||||||
|
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -788,6 +792,7 @@ const handleNotification = async (groups) => {
|
|||||||
// Create and show the notification immediately
|
// Create and show the notification immediately
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2739,6 +2744,31 @@ export async function addTimestampGroupAnnouncement({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getTimestampLatestPayment() {
|
||||||
|
const wallet = await getSaveWallet();
|
||||||
|
const address = wallet.address0;
|
||||||
|
const key = `latest-payment-${address}`;
|
||||||
|
const res = await getData<any>(key).catch(() => null);
|
||||||
|
if (res) {
|
||||||
|
const parsedData = res;
|
||||||
|
return parsedData;
|
||||||
|
} else return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addTimestampLatestPayment(timestamp) {
|
||||||
|
const wallet = await getSaveWallet();
|
||||||
|
const address = wallet.address0;
|
||||||
|
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
storeData(`latest-payment-${address}`, timestamp)
|
||||||
|
.then(() => resolve(true))
|
||||||
|
.catch((error) => {
|
||||||
|
reject(new Error(error.message || "Error saving data"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function addEnteredQmailTimestamp() {
|
export async function addEnteredQmailTimestamp() {
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
@ -3273,6 +3303,7 @@ export const checkNewMessages = async () => {
|
|||||||
// Create and show the notification
|
// Create and show the notification
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3302,6 +3333,95 @@ export const checkNewMessages = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const checkPaymentsForNotifications = async (address) => {
|
||||||
|
try {
|
||||||
|
const isDisableNotifications =
|
||||||
|
(await getUserSettings({ key: "disable-push-notifications" })) || false;
|
||||||
|
if(isDisableNotifications) return
|
||||||
|
let latestPayment = null
|
||||||
|
const savedtimestamp = await getTimestampLatestPayment();
|
||||||
|
|
||||||
|
const url = await createEndpoint(
|
||||||
|
`/transactions/search?txType=PAYMENT&address=${address}&confirmationStatus=CONFIRMED&limit=5&reverse=true`
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseData = await response.json();
|
||||||
|
|
||||||
|
const latestTx = responseData.filter(
|
||||||
|
(tx) => tx?.creatorAddress !== address && tx?.recipient === address
|
||||||
|
)[0];
|
||||||
|
if (!latestTx) {
|
||||||
|
return; // continue to the next group
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
checkDifference(latestTx.timestamp) &&
|
||||||
|
(!savedtimestamp ||
|
||||||
|
latestTx.timestamp >
|
||||||
|
savedtimestamp)
|
||||||
|
) {
|
||||||
|
if(latestTx.timestamp){
|
||||||
|
latestPayment = latestTx
|
||||||
|
await addTimestampLatestPayment(latestTx.timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save new timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
latestPayment
|
||||||
|
) {
|
||||||
|
// Create a unique notification ID with type and group announcement details
|
||||||
|
const notificationId =
|
||||||
|
encodeURIComponent("payment_notification_" +
|
||||||
|
Date.now() +
|
||||||
|
"_type=payment-announcement");
|
||||||
|
|
||||||
|
const title = "New payment!";
|
||||||
|
const body = `You have received a new payment of ${latestPayment?.amount} QORT`;
|
||||||
|
|
||||||
|
// Create and show the notification
|
||||||
|
const notification = new window.Notification(title, {
|
||||||
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
|
data: { id: notificationId },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle notification click with specific actions based on `notificationId`
|
||||||
|
notification.onclick = () => {
|
||||||
|
handleNotificationClick(notificationId);
|
||||||
|
notification.close(); // Clean up the notification on click
|
||||||
|
};
|
||||||
|
|
||||||
|
// Automatically close the notification after 5 seconds if it’s not clicked
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.close();
|
||||||
|
}, 10000); // Close after 5 seconds
|
||||||
|
|
||||||
|
const targetOrigin = window.location.origin;
|
||||||
|
|
||||||
|
window.postMessage(
|
||||||
|
{
|
||||||
|
action: "SET_PAYMENT_ANNOUNCEMENT",
|
||||||
|
payload: latestPayment,
|
||||||
|
},
|
||||||
|
targetOrigin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const checkActiveChatsForNotifications = async () => {
|
const checkActiveChatsForNotifications = async () => {
|
||||||
try {
|
try {
|
||||||
checkGroupList();
|
checkGroupList();
|
||||||
@ -3437,6 +3557,7 @@ export const checkThreads = async (bringBack) => {
|
|||||||
// Create and show the notification
|
// Create and show the notification
|
||||||
const notification = new window.Notification(title, {
|
const notification = new window.Notification(title, {
|
||||||
body,
|
body,
|
||||||
|
icon: window.location.origin + "/qortal192.png",
|
||||||
data: { id: notificationId },
|
data: { id: notificationId },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3494,6 +3615,7 @@ export const checkThreads = async (bringBack) => {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
let notificationCheckInterval
|
let notificationCheckInterval
|
||||||
|
let paymentsCheckInterval
|
||||||
|
|
||||||
const createNotificationCheck = () => {
|
const createNotificationCheck = () => {
|
||||||
// Check if an interval already exists before creating it
|
// Check if an interval already exists before creating it
|
||||||
@ -3513,6 +3635,22 @@ const createNotificationCheck = () => {
|
|||||||
}
|
}
|
||||||
}, 10 * 60 * 1000); // 10 minutes
|
}, 10 * 60 * 1000); // 10 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!paymentsCheckInterval) {
|
||||||
|
paymentsCheckInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
// This would replace the Chrome alarm callback
|
||||||
|
const wallet = await getSaveWallet();
|
||||||
|
const address = wallet?.address0;
|
||||||
|
if (!address) return;
|
||||||
|
|
||||||
|
checkPaymentsForNotifications(address);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking payments:', error);
|
||||||
|
}
|
||||||
|
}, 3 * 60 * 1000); // 3 minutes
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call this function when initializing your app
|
// Call this function when initializing your app
|
||||||
|
132
src/components/GeneralNotifications.tsx
Normal file
132
src/components/GeneralNotifications.tsx
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
ButtonBase,
|
||||||
|
Card,
|
||||||
|
MenuItem,
|
||||||
|
Popover,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import NotificationsIcon from "@mui/icons-material/Notifications";
|
||||||
|
import AccountBalanceWalletIcon from "@mui/icons-material/AccountBalanceWallet";
|
||||||
|
import { formatDate } from "../utils/time";
|
||||||
|
import { useHandlePaymentNotification } from "../hooks/useHandlePaymentNotification";
|
||||||
|
|
||||||
|
export const GeneralNotifications = ({ address }) => {
|
||||||
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
|
const {latestTx,
|
||||||
|
getNameOrAddressOfSenderMiddle,
|
||||||
|
hasNewPayment, setLastEnteredTimestampPayment, nameAddressOfSender} = useHandlePaymentNotification(address)
|
||||||
|
|
||||||
|
const handlePopupClick = (event) => {
|
||||||
|
event.stopPropagation(); // Prevent parent onClick from firing
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ButtonBase
|
||||||
|
onClick={(e) => {
|
||||||
|
handlePopupClick(e);
|
||||||
|
|
||||||
|
|
||||||
|
}}
|
||||||
|
style={{}}
|
||||||
|
>
|
||||||
|
<NotificationsIcon
|
||||||
|
sx={{
|
||||||
|
color: hasNewPayment ? "var(--unread)" : "rgba(255, 255, 255, 0.5)",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
open={!!anchorEl}
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
onClose={() => {
|
||||||
|
if(hasNewPayment){
|
||||||
|
setLastEnteredTimestampPayment(Date.now())
|
||||||
|
}
|
||||||
|
setAnchorEl(null)
|
||||||
|
|
||||||
|
}} // Close popover on click outside
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "300px",
|
||||||
|
maxWidth: "100%",
|
||||||
|
maxHeight: "60vh",
|
||||||
|
overflow: "auto",
|
||||||
|
padding: "5px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: hasNewPayment ? "flex-start" : "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!hasNewPayment && <Typography sx={{
|
||||||
|
userSelect: 'none'
|
||||||
|
}}>No new notifications</Typography>}
|
||||||
|
{hasNewPayment && (
|
||||||
|
<MenuItem
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "5px",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
textWrap: "auto",
|
||||||
|
cursor: 'default'
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
// executeEvent("addTab", { data: { service: 'APP', name: 'q-mail' } });
|
||||||
|
// executeEvent("open-apps-mode", { });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card sx={{
|
||||||
|
padding: '10px',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: "#1F2023",
|
||||||
|
gap: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "5px",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AccountBalanceWalletIcon
|
||||||
|
sx={{
|
||||||
|
color: "white",
|
||||||
|
}}
|
||||||
|
/>{" "}
|
||||||
|
{formatDate(latestTx?.timestamp)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "5px",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<Typography>{latestTx?.amount}</Typography>
|
||||||
|
</Box>
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '0.8rem'
|
||||||
|
}}>{nameAddressOfSender.current[latestTx?.creatorAddress] || getNameOrAddressOfSenderMiddle(latestTx?.creatorAddress)}</Typography>
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
116
src/hooks/useHandlePaymentNotification.tsx
Normal file
116
src/hooks/useHandlePaymentNotification.tsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
import { getBaseApiReact } from '../App';
|
||||||
|
import { getData, storeData } from '../utils/chromeStorage';
|
||||||
|
import { checkDifference, getNameInfoForOthers } from '../background';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { lastPaymentSeenTimestampAtom } from '../atoms/global';
|
||||||
|
|
||||||
|
export const useHandlePaymentNotification = (address) => {
|
||||||
|
const [latestTx, setLatestTx] = useState(null);
|
||||||
|
|
||||||
|
const nameAddressOfSender = useRef({})
|
||||||
|
const isFetchingName = useRef({})
|
||||||
|
|
||||||
|
|
||||||
|
const [lastEnteredTimestampPayment, setLastEnteredTimestampPayment] =
|
||||||
|
useRecoilState(lastPaymentSeenTimestampAtom);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (lastEnteredTimestampPayment && address) {
|
||||||
|
storeData(`last-seen-payment-${address}`, Date.now()).catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [lastEnteredTimestampPayment, address]);
|
||||||
|
|
||||||
|
const getNameOrAddressOfSender = useCallback(async(senderAddress)=> {
|
||||||
|
if(isFetchingName.current[senderAddress]) return senderAddress
|
||||||
|
try {
|
||||||
|
isFetchingName.current[senderAddress] = true
|
||||||
|
const res = await getNameInfoForOthers(senderAddress)
|
||||||
|
nameAddressOfSender.current[senderAddress] = res || senderAddress
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
isFetchingName.current[senderAddress] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const getNameOrAddressOfSenderMiddle = useCallback(async(senderAddress)=> {
|
||||||
|
getNameOrAddressOfSender(senderAddress)
|
||||||
|
return senderAddress
|
||||||
|
|
||||||
|
}, [getNameOrAddressOfSender])
|
||||||
|
|
||||||
|
const hasNewPayment = useMemo(() => {
|
||||||
|
if (!latestTx) return false;
|
||||||
|
if (!checkDifference(latestTx?.timestamp)) return false;
|
||||||
|
if (
|
||||||
|
!lastEnteredTimestampPayment ||
|
||||||
|
lastEnteredTimestampPayment < latestTx?.timestamp
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}, [lastEnteredTimestampPayment, latestTx]);
|
||||||
|
|
||||||
|
const getLastSeenData = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (!address) return;
|
||||||
|
const key = `last-seen-payment-${address}`;
|
||||||
|
|
||||||
|
const res = await getData<any>(key).catch(() => null);
|
||||||
|
if (res) {
|
||||||
|
setLastEnteredTimestampPayment(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(
|
||||||
|
`${getBaseApiReact()}/transactions/search?txType=PAYMENT&address=${address}&confirmationStatus=CONFIRMED&limit=5&reverse=true`
|
||||||
|
);
|
||||||
|
|
||||||
|
const responseData = await response.json();
|
||||||
|
|
||||||
|
const latestTx = responseData.filter(
|
||||||
|
(tx) => tx?.creatorAddress !== address && tx?.recipient === address
|
||||||
|
)[0];
|
||||||
|
if (!latestTx) {
|
||||||
|
return; // continue to the next group
|
||||||
|
}
|
||||||
|
|
||||||
|
setLatestTx(latestTx);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}, [address, setLastEnteredTimestampPayment]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getLastSeenData();
|
||||||
|
// Handler function for incoming messages
|
||||||
|
const messageHandler = (event) => {
|
||||||
|
if (event.origin !== window.location.origin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const message = event.data;
|
||||||
|
if (message?.action === "SET_PAYMENT_ANNOUNCEMENT" && message?.payload) {
|
||||||
|
setLatestTx(message.payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach the event listener
|
||||||
|
window.addEventListener("message", messageHandler);
|
||||||
|
|
||||||
|
// Clean up the event listener on component unmount
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("message", messageHandler);
|
||||||
|
};
|
||||||
|
}, [getLastSeenData]);
|
||||||
|
return {
|
||||||
|
latestTx,
|
||||||
|
getNameOrAddressOfSenderMiddle,
|
||||||
|
hasNewPayment,
|
||||||
|
setLastEnteredTimestampPayment,
|
||||||
|
nameAddressOfSender
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user