diff --git a/src/background.ts b/src/background.ts index b2fc621..fd789f2 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1683,6 +1683,54 @@ async function sendChat({ qortAddress, recipientPublicKey, message }) { return _response; } +export async function addEnteredQmailTimestampFunc() { + const wallet = await getSaveWallet(); + const address = wallet.address0; + const key = `qmail-entered-timestamp-${address}`; + + return new Promise((resolve, reject) => { + chrome.storage.local.set({ [key]: Date.now() }, () => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message || "Error saving data")); + } else { + resolve(true); + } + }); + }); +} + +// Function to retrieve the timestamp from Chrome's local storage +export async function getEnteredQmailTimestampFunc() { + const wallet = await getSaveWallet(); + const address = wallet.address0; + const key = `qmail-entered-timestamp-${address}`; + + return new Promise((resolve, reject) => { + chrome.storage.local.get([key], (result) => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message || "Error retrieving data")); + } else { + const timestamp = result[key]; + resolve(timestamp || null); + } + }); + }); +} + + async function addEnteredQmailTimestamp() { + + const response = await addEnteredQmailTimestampFunc(); + + return response +} + async function getEnteredQmailTimestamp() { + + const response = await getEnteredQmailTimestampFunc(); + + return {timestamp: response} + +} + async function sendChatGroup({ groupId, typeMessage, @@ -4428,6 +4476,28 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => { break; } + case "addEnteredQmailTimestamp": { + addEnteredQmailTimestamp() + .then((res) => { + sendResponse(res); + }) + .catch((error) => { + sendResponse({ error: error?.message }); + }); + + break; + } + case "getEnteredQmailTimestamp": { + getEnteredQmailTimestamp() + .then((res) => { + sendResponse(res); + }) + .catch((error) => { + sendResponse({ error: error?.message }); + }); + + break; + } case "logout": { try { diff --git a/src/components/Apps/useQortalMessageListener.tsx b/src/components/Apps/useQortalMessageListener.tsx index af715d6..98f6823 100644 --- a/src/components/Apps/useQortalMessageListener.tsx +++ b/src/components/Apps/useQortalMessageListener.tsx @@ -424,6 +424,20 @@ isDOMContentLoaded: false event?.data?.action === 'QDN_RESOURCE_DISPLAYED'){ const pathUrl = event?.data?.path != null ? (event?.data?.path.startsWith('/') ? '' : '/') + event?.data?.path : null setPath(pathUrl) + if(appName.toLowerCase() === 'q-mail'){ + + chrome?.runtime?.sendMessage( + { + action: "addEnteredQmailTimestamp", + payload: { + + }, + }, + (response) => { + // response + } + ); + } } else if(event?.data?.action === 'NAVIGATION_HISTORY'){ if(event?.data?.payload?.isDOMContentLoaded){ setHistory((prev)=> { diff --git a/src/components/Chat/ChatGroup.tsx b/src/components/Chat/ChatGroup.tsx index 0cf2cc6..005897e 100644 --- a/src/components/Chat/ChatGroup.tsx +++ b/src/components/Chat/ChatGroup.tsx @@ -370,7 +370,6 @@ export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey, } } socketRef.current.onerror = (e) => { - console.error('WebSocket error:', error); clearTimeout(groupSocketTimeoutRef.current); clearTimeout(timeoutIdRef.current); if (socketRef.current) { diff --git a/src/components/Group/Home.tsx b/src/components/Group/Home.tsx index 1324528..4d8e296 100644 --- a/src/components/Group/Home.tsx +++ b/src/components/Group/Home.tsx @@ -84,6 +84,7 @@ export const Home = ({ myAddress={myAddress} name={userInfo?.name} hasGroups={groups?.length !== 0} + userInfo={userInfo} /> diff --git a/src/components/Group/HomeDesktop.tsx b/src/components/Group/HomeDesktop.tsx index 23fef26..08d3190 100644 --- a/src/components/Group/HomeDesktop.tsx +++ b/src/components/Group/HomeDesktop.tsx @@ -80,6 +80,7 @@ export const HomeDesktop = ({ myAddress={myAddress} name={userInfo?.name} hasGroups={groups?.length !== 0} + userInfo={userInfo} /> { + // Current time in milliseconds + const now = Date.now(); + + // One week ago in milliseconds (7 days * 24 hours * 60 minutes * 60 seconds * 1000 milliseconds) + const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000); + + // Check if the timestamp is newer than one week ago + return timestamp > oneWeekAgo; +}; +export function formatEmailDate(timestamp: number) { + const date = moment(timestamp); + const now = moment(); + + if (date.isSame(now, 'day')) { + // If the email was received today, show the time + return date.format('h:mm A'); + } else if (date.isSame(now, 'year')) { + // If the email was received this year, show the month and day + return date.format('MMM D'); + } else { + // For older emails, show the full date + return date.format('MMM D, YYYY'); + } +} +export const QMailMessages = ({userName, userAddress}) => { + const [mails, setMails] = useState([]) + const [lastEnteredTimestamp, setLastEnteredTimestamp] = useState(null) + const [loading, setLoading] = useState(true) + + console.log('lastEnteredTimestamp', lastEnteredTimestamp) + const getMails = useCallback(async () => { + try { + setLoading(true) + const query = `qortal_qmail_${userName.slice( + 0, + 20 + )}_${userAddress.slice(-6)}_mail_` + const response = await fetch(`${getBaseApiReact()}/arbitrary/resources/search?service=MAIL_PRIVATE&query=${query}&limit=10&includemetadata=false&offset=0&reverse=true&excludeblocked=true&mode=ALL`); + const mailData = await response.json(); + + + setMails(mailData); + } catch (error) { + console.error(error); + } finally { + setLoading(false) + + } + }, []) + + const getTimestamp = async () => { + try { + return new Promise((res, rej) => { + chrome?.runtime?.sendMessage( + { + action: "getEnteredQmailTimestamp", + payload: {}, + }, + (response) => { + if (!response?.error) { + setLastEnteredTimestamp(response?.timestamp) + } + + } + ); + + }); + } catch (error) {} + }; + + useEffect(() => { + getTimestamp() + if(!userName || !userAddress) return + getMails(); + + const interval = setInterval(() => { + getTimestamp() + getMails(); + }, 300000); + + return () => clearInterval(interval); + + }, [getMails, userName, userAddress]); + + + + console.log('mails', mails) + return ( + + + + + Latest Q-Mails + + + + + + {loading && mails.length === 0 && ( + + + + )} + {!loading && mails.length === 0 && ( + + + Nothing to display + + + )} + + + {mails?.map((mail)=> { + return ( + { + executeEvent("addTab", { data: { service: 'APP', name: 'q-mail' } }); + executeEvent("open-apps-mode", { }); + }} + > + + + + {!lastEnteredTimestamp && isLessThanOneWeekOld(mail?.created) ? ( + + ) : !lastEnteredTimestamp ? ( + + ): lastEnteredTimestamp < mail?.created ? ( + + ) : ( + + ) + } + + + + + + + ) + })} + + + + + + + + ) +} diff --git a/src/components/Group/ThingsToDoInitial.tsx b/src/components/Group/ThingsToDoInitial.tsx index 28c3889..9bcd6d9 100644 --- a/src/components/Group/ThingsToDoInitial.tsx +++ b/src/components/Group/ThingsToDoInitial.tsx @@ -11,8 +11,9 @@ import InfoIcon from "@mui/icons-material/Info"; import { Box, Typography } from "@mui/material"; import { Spacer } from "../../common/Spacer"; import { isMobile } from "../../App"; +import { QMailMessages } from "./QMailMessages"; -export const ThingsToDoInitial = ({ myAddress, name, hasGroups, balance }) => { +export const ThingsToDoInitial = ({ myAddress, name, hasGroups, balance, userInfo }) => { const [checked1, setChecked1] = React.useState(false); const [checked2, setChecked2] = React.useState(false); const [checked3, setChecked3] = React.useState(false); @@ -47,6 +48,23 @@ export const ThingsToDoInitial = ({ myAddress, name, hasGroups, balance }) => { if (name) setChecked2(true); }, [name]); + + const isLoaded = React.useMemo(()=> { + if(balance !== null && userInfo !== null) return true + return false +}, [balance, userInfo]) + +const hasDoneNameAndBalanceAndIsLoaded = React.useMemo(()=> { + if(isLoaded && checked1 && checked2) return true +return false +}, [checked1, isLoaded, checked2]) + +if(hasDoneNameAndBalanceAndIsLoaded){ +return ( + +); +} + return ( { fontWeight: 600, }} > - Getting Started: + {!isLoaded ? 'Loading...' : 'Getting Started' } +