mobile new design

This commit is contained in:
2024-09-21 07:48:54 +03:00
parent f9c6f4c5fd
commit 38545e3da5
18 changed files with 1778 additions and 1122 deletions

View File

@@ -6,7 +6,7 @@ import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import Tiptap from './TipTap'
import { CustomButton } from '../../App-styles'
import CircularProgress from '@mui/material/CircularProgress';
import { Box, Input, Typography } from '@mui/material';
import { Box, ButtonBase, Input, Typography } from '@mui/material';
import { LoadingSnackbar } from '../Snackbar/LoadingSnackbar';
import { getNameInfo } from '../Group/Group';
import { Spacer } from '../../common/Spacer';
@@ -17,12 +17,14 @@ import { useMessageQueue } from '../../MessageQueueContext';
import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import ShortUniqueId from "short-unique-id";
import { ReturnIcon } from '../../assets/Icons/ReturnIcon';
import { ExitIcon } from '../../assets/Icons/ExitIcon';
const uid = new ShortUniqueId({ length: 5 });
export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName, balance, close}) => {
export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName, balance, close, setMobileViewModeKeepOpen}) => {
const { queueChats, addToQueue, processWithNewMessages} = useMessageQueue();
const [isFocusedParent, setIsFocusedParent] = useState(false);
@@ -344,27 +346,69 @@ const clearEditorContent = () => {
flexDirection: 'column',
width: '100%'
}}>
<Box onClick={close} sx={{
display: 'flex',
alignItems: 'center',
gap: '5px',
cursor: 'pointer',
padding: '4px 6px',
width: 'fit-content',
borderRadius: '3px',
background: 'rgb(35, 36, 40)',
margin: '10px 0px',
alignSelf: 'center'
}}>
<ArrowBackIcon sx={{
color: 'white',
fontSize: isMobile ? '20px' : '20px'
}}/>
<Typography sx={{
color: 'white',
fontSize: isMobile ? '14px' : '14px'
}}>Close Direct Chat</Typography>
</Box>
{isMobile && (
<Box
sx={{
display: "flex",
alignItems: "center",
width: "100%",
marginTop: "14px",
justifyContent: "center",
height: "15px",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "320px",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
width: "50px",
}}
>
<ButtonBase
onClick={() => {
close()
}}
>
<ReturnIcon />
</ButtonBase>
</Box>
<Typography
sx={{
fontSize: "14px",
fontWeight: 600,
}}
>
{isNewChat ? '' : selectedDirect?.name || (selectedDirect?.address?.slice(0,10) + '...')}
</Typography>
<Box
sx={{
display: "flex",
alignItems: "center",
width: "50px",
justifyContent: "flex-end",
}}
>
<ButtonBase
onClick={() => {
setSelectedDirect(null)
setMobileViewModeKeepOpen('')
setNewChat(false)
}}
>
<ExitIcon />
</ButtonBase>
</Box>
</Box>
</Box>
)}
{isNewChat && (
<>
<Spacer height="30px" />
@@ -376,7 +420,7 @@ const clearEditorContent = () => {
</>
)}
<ChatList initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
<ChatList chatId={selectedDirect?.address} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
<div style={{

View File

@@ -374,7 +374,7 @@ const clearEditorContent = () => {
left: hide && '-100000px',
}}>
<ChatList initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
<ChatList chatId={selectedGroup} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
<div style={{

View File

@@ -3,18 +3,21 @@ import { List, AutoSizer, CellMeasurerCache, CellMeasurer } from 'react-virtuali
import { MessageItem } from './MessageItem';
import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
const cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 50,
});
// const cache = new CellMeasurerCache({
// fixedWidth: true,
// defaultHeight: 50,
// });
export const ChatList = ({ initialMessages, myAddress, tempMessages }) => {
export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) => {
const hasLoadedInitialRef = useRef(false);
const listRef = useRef();
const [messages, setMessages] = useState(initialMessages);
const [showScrollButton, setShowScrollButton] = useState(false);
const cache = useMemo(() => new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 50,
}), [chatId]); // Recreate cache when chatId changes
useEffect(() => {
cache.clearAll();
@@ -175,7 +178,7 @@ let uniqueInitialMessages = Array.from(uniqueInitialMessagesMap.values()).sort((
// }, [messages, myAddress]);
return (
<div style={{ position: 'relative', flexGrow: 1, width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
<div style={{ position: 'relative', marginTop: '14px', flexGrow: 1, width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
<AutoSizer>
{({ height, width }) => (
<List

View File

@@ -25,21 +25,28 @@ import { Spacer } from "../../common/Spacer";
import ShortUniqueId from "short-unique-id";
import { AnnouncementList } from "./AnnouncementList";
const uid = new ShortUniqueId({ length: 8 });
import CampaignIcon from '@mui/icons-material/Campaign';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import CampaignIcon from "@mui/icons-material/Campaign";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { AnnouncementDiscussion } from "./AnnouncementDiscussion";
import { MyContext, getArbitraryEndpointReact, getBaseApiReact, isMobile, pauseAllQueues, resumeAllQueues } from "../../App";
import {
MyContext,
getArbitraryEndpointReact,
getBaseApiReact,
isMobile,
pauseAllQueues,
resumeAllQueues,
} from "../../App";
import { RequestQueueWithPromise } from "../../utils/queue/queue";
import { CustomizedSnackbars } from "../Snackbar/Snackbar";
import { addDataPublishesFunc, getDataPublishesFunc } from "../Group/Group";
import { addDataPublishesFunc, getDataPublishesFunc } from "../Group/Group";
import { getRootHeight } from "../../utils/mobile/mobileUtils";
export const requestQueueCommentCount = new RequestQueueWithPromise(3)
export const requestQueuePublishedAccouncements = new RequestQueueWithPromise(3)
export const requestQueueCommentCount = new RequestQueueWithPromise(3);
export const requestQueuePublishedAccouncements = new RequestQueueWithPromise(
3
);
export const saveTempPublish = async ({ data, key }: any) => {
return new Promise((res, rej) => {
chrome?.runtime?.sendMessage(
{
@@ -50,10 +57,9 @@ export const saveTempPublish = async ({ data, key }: any) => {
},
},
(response) => {
if (!response?.error) {
res(response);
return
return;
}
rej(response.error);
}
@@ -62,19 +68,16 @@ export const saveTempPublish = async ({ data, key }: any) => {
};
export const getTempPublish = async () => {
return new Promise((res, rej) => {
chrome?.runtime?.sendMessage(
{
action: "getTempPublish",
payload: {
},
payload: {},
},
(response) => {
if (!response?.error) {
res(response);
return
return;
}
rej(response.error);
}
@@ -95,7 +98,6 @@ export const decryptPublishes = async (encryptedMessages: any[], secretKey) => {
},
},
(response) => {
if (!response?.error) {
res(response);
// if(hasInitialized.current){
@@ -130,13 +132,13 @@ export const GroupAnnouncements = ({
handleNewEncryptionNotification,
isAdmin,
hide,
myName
myName,
}) => {
const [messages, setMessages] = useState([]);
const [isSending, setIsSending] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [announcements, setAnnouncements] = useState([]);
const [tempPublishedList, setTempPublishedList] = useState([])
const [tempPublishedList, setTempPublishedList] = useState([]);
const [announcementData, setAnnouncementData] = useState({});
const [selectedAnnouncement, setSelectedAnnouncement] = useState(null);
const [isFocusedParent, setIsFocusedParent] = useState(false);
@@ -147,37 +149,45 @@ export const GroupAnnouncements = ({
const hasInitialized = useRef(false);
const hasInitializedWebsocket = useRef(false);
const editorRef = useRef(null);
const dataPublishes = useRef({})
const dataPublishes = useRef({});
const setEditorRef = (editorInstance) => {
editorRef.current = editorInstance;
};
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
useEffect(()=> {
if(!selectedGroup) return
(async ()=> {
const res = await getDataPublishesFunc(selectedGroup, 'anc')
dataPublishes.current = res || {}
})()
}, [selectedGroup])
const triggerRerender = () => {
forceUpdate(); // Trigger re-render by updating the state
};
useEffect(() => {
if (!selectedGroup) return;
(async () => {
const res = await getDataPublishesFunc(selectedGroup, "anc");
dataPublishes.current = res || {};
})();
}, [selectedGroup]);
const getAnnouncementData = async ({ identifier, name, resource }) => {
try {
let data = dataPublishes.current[`${name}-${identifier}`]
if(!data || (data?.update || data?.created !== (resource?.updated || resource?.created))){
const res = await requestQueuePublishedAccouncements.enqueue(()=> {
let data = dataPublishes.current[`${name}-${identifier}`];
if (
!data ||
data?.update ||
data?.created !== (resource?.updated || resource?.created)
) {
const res = await requestQueuePublishedAccouncements.enqueue(() => {
return fetch(
`${getBaseApiReact()}/arbitrary/DOCUMENT/${name}/${identifier}?encoding=base64`
);
})
if(!res?.ok) return
data = await res.text();
await addDataPublishesFunc({...resource, data}, selectedGroup, 'anc')
});
if (!res?.ok) return;
data = await res.text();
await addDataPublishesFunc({ ...resource, data }, selectedGroup, "anc");
} else {
data = data.data
data = data.data;
}
const response = await decryptPublishes([{ data }], secretKey);
const messageData = response[0];
setAnnouncementData((prev) => {
return {
@@ -185,16 +195,11 @@ export const GroupAnnouncements = ({
[`${identifier}-${name}`]: messageData,
};
});
} catch (error) {
console.log('error', error)
console.log("error", error);
}
};
useEffect(() => {
if (!secretKey || hasInitializedWebsocket.current) return;
setIsLoading(true);
@@ -226,64 +231,61 @@ export const GroupAnnouncements = ({
};
const publishAnc = async ({ encryptedData, identifier }: any) => {
return new Promise((res, rej) => {
chrome?.runtime?.sendMessage(
{
action: "publishGroupEncryptedResource",
payload: {
encryptedData,
identifier,
},
return new Promise((res, rej) => {
chrome?.runtime?.sendMessage(
{
action: "publishGroupEncryptedResource",
payload: {
encryptedData,
identifier,
},
(response) => {
if (!response?.error) {
res(response);
}
rej(response.error);
},
(response) => {
if (!response?.error) {
res(response);
}
);
});
rej(response.error);
}
);
});
};
const clearEditorContent = () => {
if (editorRef.current) {
editorRef.current.chain().focus().clearContent().run();
if(isMobile){
if (isMobile) {
setTimeout(() => {
editorRef.current?.chain().blur().run();
setIsFocusedParent(false)
editorRef.current?.chain().blur().run();
setIsFocusedParent(false);
setTimeout(() => {
triggerRerender();
}, 300);
}, 200);
}
}
};
const setTempData = async ()=> {
const setTempData = async () => {
try {
const getTempAnnouncements = await getTempPublish()
if(getTempAnnouncements?.announcement){
let tempData = []
Object.keys(getTempAnnouncements?.announcement || {}).map((key)=> {
const value = getTempAnnouncements?.announcement[key]
tempData.push(value.data)
})
setTempPublishedList(tempData)
}
} catch (error) {
}
}
const getTempAnnouncements = await getTempPublish();
if (getTempAnnouncements?.announcement) {
let tempData = [];
Object.keys(getTempAnnouncements?.announcement || {}).map((key) => {
const value = getTempAnnouncements?.announcement[key];
tempData.push(value.data);
});
setTempPublishedList(tempData);
}
} catch (error) {}
};
const publishAnnouncement = async () => {
try {
pauseAllQueues()
const fee = await getFee('ARBITRARY')
pauseAllQueues();
const fee = await getFee("ARBITRARY");
await show({
message: "Would you like to perform a ARBITRARY transaction?" ,
publishFee: fee.fee + ' QORT'
})
message: "Would you like to perform a ARBITRARY transaction?",
publishFee: fee.fee + " QORT",
});
if (isSending) return;
if (editorRef.current) {
const htmlContent = editorRef.current.getHTML();
@@ -292,8 +294,8 @@ export const GroupAnnouncements = ({
const message = {
version: 1,
extra: {},
message: htmlContent
}
message: htmlContent,
};
const secretKeyObject = await getSecretKey(false, true);
const message64: any = await objectToBase64(message);
const encryptSingle = await encryptChatMessage(
@@ -304,36 +306,37 @@ export const GroupAnnouncements = ({
const identifier = `grp-${selectedGroup}-anc-${randomUid}`;
const res = await publishAnc({
encryptedData: encryptSingle,
identifier
identifier,
});
const dataToSaveToStorage = {
name: myName,
identifier,
service: 'DOCUMENT',
service: "DOCUMENT",
tempData: message,
created: Date.now()
}
await saveTempPublish({data: dataToSaveToStorage, key: 'announcement'})
setTempData()
created: Date.now(),
};
await saveTempPublish({
data: dataToSaveToStorage,
key: "announcement",
});
setTempData();
clearEditorContent();
}
// send chat message
} catch (error) {
if(!error) return
if (!error) return;
setInfoSnack({
type: "error",
message: error,
});
setOpenSnack(true)
setOpenSnack(true);
} finally {
resumeAllQueues()
resumeAllQueues();
setIsSending(false);
}
};
const getAnnouncements = React.useCallback(
async (selectedGroup) => {
try {
@@ -349,12 +352,16 @@ export const GroupAnnouncements = ({
},
});
const responseData = await response.json();
setTempData()
setTempData();
setAnnouncements(responseData);
setIsLoading(false);
for (const data of responseData) {
getAnnouncementData({ name: data.name, identifier: data.identifier, resource: data });
getAnnouncementData({
name: data.name,
identifier: data.identifier,
resource: data,
});
}
} catch (error) {
} finally {
@@ -363,199 +370,206 @@ export const GroupAnnouncements = ({
},
[secretKey]
);
React.useEffect(() => {
if (selectedGroup && secretKey && !hasInitialized.current && !hide) {
getAnnouncements(selectedGroup);
hasInitialized.current = true
hasInitialized.current = true;
}
}, [selectedGroup, secretKey, hide]);
const loadMore = async()=> {
const loadMore = async () => {
try {
setIsLoading(true);
const offset = announcements.length
const identifier = `grp-${selectedGroup}-anc-`;
const url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=20&includemetadata=false&offset=${offset}&reverse=true&prefix=true`;
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const responseData = await response.json();
const offset = announcements.length;
const identifier = `grp-${selectedGroup}-anc-`;
const url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=20&includemetadata=false&offset=${offset}&reverse=true&prefix=true`;
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const responseData = await response.json();
setAnnouncements((prev)=> [...prev, ...responseData]);
setIsLoading(false);
setAnnouncements((prev) => [...prev, ...responseData]);
setIsLoading(false);
for (const data of responseData) {
getAnnouncementData({ name: data.name, identifier: data.identifier });
}
} catch (error) {}
};
const interval = useRef<any>(null);
const checkNewMessages = React.useCallback(async () => {
try {
const identifier = `grp-${selectedGroup}-anc-`;
const url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=20&includemetadata=false&offset=${0}&reverse=true&prefix=true`;
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const responseData = await response.json();
const latestMessage = announcements[0];
if (!latestMessage) {
for (const data of responseData) {
getAnnouncementData({ name: data.name, identifier: data.identifier });
}
} catch (error) {
}
}
const interval = useRef<any>(null)
const checkNewMessages = React.useCallback(
async () => {
try {
const identifier = `grp-${selectedGroup}-anc-`;
const url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=20&includemetadata=false&offset=${0}&reverse=true&prefix=true`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
const responseData = await response.json()
const latestMessage = announcements[0]
if (!latestMessage) {
for (const data of responseData) {
try {
getAnnouncementData({ name: data.name, identifier: data.identifier });
} catch (error) {}
}
setAnnouncements(responseData)
return
}
const findMessage = responseData?.findIndex(
(item: any) => item?.identifier === latestMessage?.identifier
)
if(findMessage === -1) return
const newArray = responseData.slice(0, findMessage)
for (const data of newArray) {
try {
getAnnouncementData({ name: data.name, identifier: data.identifier });
getAnnouncementData({
name: data.name,
identifier: data.identifier,
});
} catch (error) {}
}
setAnnouncements((prev)=> [...newArray, ...prev])
} catch (error) {
} finally {
setAnnouncements(responseData);
return;
}
},
[announcements, secretKey, selectedGroup]
)
const findMessage = responseData?.findIndex(
(item: any) => item?.identifier === latestMessage?.identifier
);
if (findMessage === -1) return;
const newArray = responseData.slice(0, findMessage);
for (const data of newArray) {
try {
getAnnouncementData({ name: data.name, identifier: data.identifier });
} catch (error) {}
}
setAnnouncements((prev) => [...newArray, ...prev]);
} catch (error) {
} finally {
}
}, [announcements, secretKey, selectedGroup]);
const checkNewMessagesFunc = useCallback(() => {
let isCalling = false
let isCalling = false;
interval.current = setInterval(async () => {
if (isCalling) return
isCalling = true
const res = await checkNewMessages()
isCalling = false
}, 20000)
}, [checkNewMessages])
if (isCalling) return;
isCalling = true;
const res = await checkNewMessages();
isCalling = false;
}, 20000);
}, [checkNewMessages]);
useEffect(() => {
if(!secretKey || hide) return
checkNewMessagesFunc()
if (!secretKey || hide) return;
checkNewMessagesFunc();
return () => {
if (interval?.current) {
clearInterval(interval.current)
clearInterval(interval.current);
}
}
}, [checkNewMessagesFunc, hide])
};
}, [checkNewMessagesFunc, hide]);
const combinedListTempAndReal = useMemo(() => {
// Combine the two lists
const combined = [...tempPublishedList, ...announcements];
// Remove duplicates based on the "identifier"
const uniqueItems = new Map();
combined.forEach(item => {
uniqueItems.set(item.identifier, item); // This will overwrite duplicates, keeping the last occurrence
combined.forEach((item) => {
uniqueItems.set(item.identifier, item); // This will overwrite duplicates, keeping the last occurrence
});
// Convert the map back to an array and sort by "created" timestamp in descending order
const sortedList = Array.from(uniqueItems.values()).sort((a, b) => b.created - a.created);
const sortedList = Array.from(uniqueItems.values()).sort(
(a, b) => b.created - a.created
);
return sortedList;
}, [tempPublishedList, announcements]);
if(selectedAnnouncement){
if (selectedAnnouncement) {
return (
<div
style={{
height: isMobile ? `calc(${getRootHeight()} - 83px` : "100vh",
display: "flex",
flexDirection: "column",
width: "100%",
visibility: hide && 'hidden',
position: hide && 'fixed',
left: hide && '-1000px'
}}
>
<AnnouncementDiscussion myName={myName} show={show} secretKey={secretKey} selectedAnnouncement={selectedAnnouncement} setSelectedAnnouncement={setSelectedAnnouncement} encryptChatMessage={encryptChatMessage} getSecretKey={getSecretKey} />
style={{
// reference to change height
height: isMobile ? `calc(${getRootHeight()} - 127px` : "100vh",
display: "flex",
flexDirection: "column",
width: "100%",
visibility: hide && "hidden",
position: hide && "fixed",
left: hide && "-1000px",
}}
>
<AnnouncementDiscussion
myName={myName}
show={show}
secretKey={secretKey}
selectedAnnouncement={selectedAnnouncement}
setSelectedAnnouncement={setSelectedAnnouncement}
encryptChatMessage={encryptChatMessage}
getSecretKey={getSecretKey}
/>
</div>
)
);
}
return (
<div
style={{
height: isMobile ? `calc(${getRootHeight()} - 83px` : "100vh",
// reference to change height
height: isMobile ? `calc(${getRootHeight()} - 127px` : "100vh",
display: "flex",
flexDirection: "column",
width: "100%",
visibility: hide && 'hidden',
position: hide && 'fixed',
left: hide && '-1000px'
visibility: hide && "hidden",
position: hide && "fixed",
left: hide && "-1000px",
}}
>
<div style={{
position: "relative",
width: "100%",
display: "flex",
flexDirection: "column",
flexShrink: 0,
}}>
{!isMobile && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
padding: isMobile ? '8px' : "25px",
fontSize: isMobile ? '16px' : "20px",
gap: '20px',
alignItems: 'center'
}}
>
<CampaignIcon sx={{
fontSize: isMobile ? '16px' : '30px'
}} />
Group Announcements
</Box>
)}
<Spacer height={isMobile ? "0px" : "25px"} />
<div
style={{
position: "relative",
width: "100%",
display: "flex",
flexDirection: "column",
flexShrink: 0,
}}
>
{!isMobile && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
padding: isMobile ? "8px" : "25px",
fontSize: isMobile ? "16px" : "20px",
gap: "20px",
alignItems: "center",
}}
>
<CampaignIcon
sx={{
fontSize: isMobile ? "16px" : "30px",
}}
/>
Group Announcements
</Box>
)}
<Spacer height={isMobile ? "0px" : "25px"} />
</div>
{!isLoading && combinedListTempAndReal?.length === 0 && (
<Box sx={{
width: '100%',
display: 'flex',
justifyContent: 'center'
}}>
<Typography sx={{
fontSize: '16px'
}}>No announcements</Typography>
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
}}
>
No announcements
</Typography>
</Box>
)}
<AnnouncementList
@@ -563,118 +577,126 @@ export const GroupAnnouncements = ({
initialMessages={combinedListTempAndReal}
setSelectedAnnouncement={setSelectedAnnouncement}
disableComment={false}
showLoadMore={announcements.length > 0 && announcements.length % 20 === 0}
showLoadMore={
announcements.length > 0 && announcements.length % 20 === 0
}
loadMore={loadMore}
myName={myName}
/>
{isAdmin && (
<div
style={{
// position: 'fixed',
// bottom: '0px',
backgroundColor: "#232428",
minHeight: isMobile ? "0px" : "150px",
maxHeight: isMobile ? "auto" : "400px",
display: "flex",
flexDirection: "column",
overflow: "hidden",
width: "100%",
boxSizing: "border-box",
padding: isMobile ? "10px": "20px",
position: isFocusedParent ? 'fixed' : 'relative',
bottom: isFocusedParent ? '0px' : 'unset',
top: isFocusedParent ? '0px' : 'unset',
zIndex: isFocusedParent ? 5 : 'unset',
flexShrink: 0
}}
>
<div
style={{
display: "flex",
flexDirection: "column",
flexGrow: isMobile && 1,
overflow: "auto",
// height: '100%',
}}
>
<Tiptap
setEditorRef={setEditorRef}
onEnter={publishAnnouncement}
disableEnter
maxHeightOffset="40px"
isFocusedParent={isFocusedParent} setIsFocusedParent={setIsFocusedParent}
/>
</div>
<Box sx={{
display: 'flex',
width: '100&',
gap: '10px',
justifyContent: 'center',
flexShrink: 0,
position: 'relative',
}}>
{isFocusedParent && (
<CustomButton
onClick={()=> {
if(isSending) return
setIsFocusedParent(false)
clearEditorContent()
// Unfocus the editor
}}
style={{
marginTop: 'auto',
alignSelf: 'center',
cursor: isSending ? 'default' : 'pointer',
background: 'red',
flexShrink: 0,
padding: isMobile && '5px',
fontSize: isMobile && '14px',
}}
>
{` Close`}
</CustomButton>
{isAdmin && (
<div
style={{
// position: 'fixed',
// bottom: '0px',
backgroundColor: "#232428",
minHeight: isMobile ? "0px" : "150px",
maxHeight: isMobile ? "auto" : "400px",
display: "flex",
flexDirection: "column",
overflow: "hidden",
width: "100%",
boxSizing: "border-box",
padding: isMobile ? "10px" : "20px",
position: isFocusedParent ? "fixed" : "relative",
bottom: isFocusedParent ? "0px" : "unset",
top: isFocusedParent ? "0px" : "unset",
zIndex: isFocusedParent ? 5 : "unset",
flexShrink: 0,
}}
>
<div
style={{
display: "flex",
flexDirection: "column",
flexGrow: isMobile && 1,
overflow: "auto",
// height: '100%',
}}
>
<Tiptap
setEditorRef={setEditorRef}
onEnter={publishAnnouncement}
disableEnter
maxHeightOffset="40px"
isFocusedParent={isFocusedParent}
setIsFocusedParent={setIsFocusedParent}
/>
</div>
<Box
sx={{
display: "flex",
width: "100&",
gap: "10px",
justifyContent: "center",
flexShrink: 0,
position: "relative",
}}
>
{isFocusedParent && (
<CustomButton
onClick={() => {
if (isSending) return;
setIsFocusedParent(false);
clearEditorContent();
setTimeout(() => {
triggerRerender();
}, 300);
// Unfocus the editor
}}
style={{
marginTop: "auto",
alignSelf: "center",
cursor: isSending ? "default" : "pointer",
background: "red",
flexShrink: 0,
padding: isMobile && "5px",
fontSize: isMobile && "14px",
}}
>
{` Close`}
</CustomButton>
)}
<CustomButton
onClick={() => {
if (isSending) return;
publishAnnouncement();
}}
style={{
marginTop: "auto",
alignSelf: "center",
cursor: isSending ? "default" : "pointer",
background: isSending && "rgba(0, 0, 0, 0.8)",
flexShrink: 0,
padding: isMobile && '5px',
fontSize: isMobile && '14px',
<CustomButton
onClick={() => {
if (isSending) return;
publishAnnouncement();
}}
style={{
marginTop: "auto",
alignSelf: "center",
cursor: isSending ? "default" : "pointer",
background: isSending && "rgba(0, 0, 0, 0.8)",
flexShrink: 0,
padding: isMobile && "5px",
fontSize: isMobile && "14px",
}}
>
{isSending && (
<CircularProgress
size={18}
sx={{
position: "absolute",
top: "50%",
left: "50%",
marginTop: "-12px",
marginLeft: "-12px",
color: "white",
}}
/>
)}
{` Publish Announcement`}
</CustomButton>
</Box>
</div>
)}
}}
>
{isSending && (
<CircularProgress
size={18}
sx={{
position: "absolute",
top: "50%",
left: "50%",
marginTop: "-12px",
marginLeft: "-12px",
color: "white",
}}
/>
)}
{` Publish Announcement`}
</CustomButton>
</Box>
</div>
)}
<CustomizedSnackbars open={openSnack} setOpen={setOpenSnack} info={infoSnack} setInfo={setInfoSnack} />
<CustomizedSnackbars
open={openSnack}
setOpen={setOpenSnack}
info={infoSnack}
setInfo={setInfoSnack}
/>
<LoadingSnackbar
open={isLoading}

View File

@@ -7,6 +7,7 @@ import React, {
} from "react";
import { GroupMail } from "../Group/Forum/GroupMail";
import { isMobile } from "../../App";
import { getRootHeight } from "../../utils/mobile/mobileUtils";
@@ -36,7 +37,8 @@ export const GroupForum = ({
return (
<div
style={{
height: isMobile ? '100%' : "100vh",
// reference to change height
height: isMobile ? `calc(${getRootHeight()} - 127px` : "100vh",
display: "flex",
flexDirection: "column",
width: "100%",

View File

@@ -445,7 +445,7 @@ export const NewThread = ({
sx={{
backgroundColor: "#434448",
padding: isMobile ? '5px' : "20px 42px",
height: "calc(100% - 150px)",
height: "calc(100% - 165px)",
flexShrink: 0,
}}
>

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ import { ChatIcon } from "../../assets/Icons/ChatIcon";
import { ThreadsIcon } from "../../assets/Icons/ThreadsIcon";
import { MembersIcon } from "../../assets/Icons/MembersIcon";
export const GroupMenu = ({ setGroupSection, groupSection }) => {
export const GroupMenu = ({ setGroupSection, groupSection, setOpenManageMembers }) => {
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
@@ -177,7 +177,7 @@ export const GroupMenu = ({ setGroupSection, groupSection }) => {
</MenuItem>
<MenuItem
onClick={() => {
// setGroupSection("")
setOpenManageMembers(true)
handleClose();
}}
>

View File

@@ -1,32 +1,58 @@
import { Box, Button, Typography } from '@mui/material'
import React from 'react'
import { Spacer } from '../../common/Spacer'
import { ListOfThreadPostsWatched } from './ListOfThreadPostsWatched'
import { ThingsToDoInitial } from './ThingsToDoInitial'
import { GroupJoinRequests } from './GroupJoinRequests'
import { GroupInvites } from './GroupInvites'
import { Box, Button, Typography } from "@mui/material";
import React from "react";
import { Spacer } from "../../common/Spacer";
import { ListOfThreadPostsWatched } from "./ListOfThreadPostsWatched";
import { ThingsToDoInitial } from "./ThingsToDoInitial";
import { GroupJoinRequests } from "./GroupJoinRequests";
import { GroupInvites } from "./GroupInvites";
import RefreshIcon from "@mui/icons-material/Refresh";
export const Home = ({refreshHomeDataFunc, myAddress, isLoadingGroups, balance, userInfo, groups, setGroupSection, setSelectedGroup, getTimestampEnterChat, setOpenManageMembers, setOpenAddGroup, setMobileViewMode}) => {
export const Home = ({
refreshHomeDataFunc,
myAddress,
isLoadingGroups,
balance,
userInfo,
groups,
setGroupSection,
setSelectedGroup,
getTimestampEnterChat,
setOpenManageMembers,
setOpenAddGroup,
setMobileViewMode,
}) => {
return (
<Box
sx={{
display: "flex",
width: "100%",
flexDirection: "column",
height: "100%",
overflow: "auto",
alignItems: "center"
}}
>
<Spacer height="20px" />
<Typography sx={{ color: 'rgba(255, 255, 255, 1)', fontWeight: 400, fontSize: '24px'}}>
<Spacer height="16px" />
Welcome
</Typography>
<Spacer height="26px" />
sx={{
display: "flex",
width: "100%",
flexDirection: "column",
height: "100%",
overflow: "auto",
alignItems: "center",
}}
>
<Spacer height="20px" />
<Typography
sx={{
color: "rgba(255, 255, 255, 1)",
fontWeight: 400,
fontSize: userInfo?.name?.length > 15 ? "16px" : "20px",
padding: '10px'
}}
>
Welcome{" "}
{userInfo?.name ? (
<span
style={{
fontStyle: "italic",
}}
>{`, ${userInfo?.name}`}</span>
) : null}
</Typography>
<Spacer height="26px" />
{/* <Box
{/* <Box
sx={{
display: "flex",
width: "100%",
@@ -44,42 +70,41 @@ export const Home = ({refreshHomeDataFunc, myAddress, isLoadingGroups, balance,
Refresh home data
</Button>
</Box> */}
{!isLoadingGroups && (
<Box
sx={{
display: "flex",
gap: "15px",
flexWrap: "wrap",
justifyContent: "center",
}}
>
{!isLoadingGroups && (
<Box
sx={{
display: "flex",
gap: "15px",
flexWrap: "wrap",
justifyContent: "center",
}}
>
<ThingsToDoInitial
balance={balance}
myAddress={myAddress}
name={userInfo?.name}
hasGroups={groups?.length !== 0}
/>
<ListOfThreadPostsWatched />
<ThingsToDoInitial
balance={balance}
myAddress={myAddress}
name={userInfo?.name}
hasGroups={groups?.length !== 0}
/>
<ListOfThreadPostsWatched />
<GroupJoinRequests
setGroupSection={setGroupSection}
setSelectedGroup={setSelectedGroup}
getTimestampEnterChat={getTimestampEnterChat}
setOpenManageMembers={setOpenManageMembers}
myAddress={myAddress}
groups={groups}
setMobileViewMode={setMobileViewMode}
/>
<GroupInvites
setOpenAddGroup={setOpenAddGroup}
myAddress={myAddress}
groups={groups}
setMobileViewMode={setMobileViewMode}
/>
</Box>
)}
<Spacer height="180px" />
</Box>
)
}
<GroupJoinRequests
setGroupSection={setGroupSection}
setSelectedGroup={setSelectedGroup}
getTimestampEnterChat={getTimestampEnterChat}
setOpenManageMembers={setOpenManageMembers}
myAddress={myAddress}
groups={groups}
setMobileViewMode={setMobileViewMode}
/>
<GroupInvites
setOpenAddGroup={setOpenAddGroup}
myAddress={myAddress}
groups={groups}
setMobileViewMode={setMobileViewMode}
/>
</Box>
)}
<Spacer height="180px" />
</Box>
);
};

View File

@@ -253,6 +253,7 @@ export const ManageMembers = ({
sx={{
width: "100%",
padding: "25px",
maxWidth: '750px'
}}
>
<ListOfMembers
@@ -271,6 +272,7 @@ export const ManageMembers = ({
sx={{
width: "100%",
padding: "25px",
maxWidth: '750px'
}}
>
<InviteMember show={show} groupId={selectedGroup?.groupId} setOpenSnack={setOpenSnack} setInfoSnack={setInfoSnack} />
@@ -281,7 +283,8 @@ export const ManageMembers = ({
<Box
sx={{
width: "100%",
padding: "25px",
padding: "25px",
maxWidth: '750px'
}}
>
<ListOfInvites show={show} groupId={selectedGroup?.groupId} setOpenSnack={setOpenSnack} setInfoSnack={setInfoSnack} />
@@ -293,7 +296,8 @@ export const ManageMembers = ({
<Box
sx={{
width: "100%",
padding: "25px",
padding: "25px",
maxWidth: '750px'
}}
>
<ListOfBans show={show} groupId={selectedGroup?.groupId} setOpenSnack={setOpenSnack} setInfoSnack={setInfoSnack} />
@@ -304,7 +308,8 @@ export const ManageMembers = ({
<Box
sx={{
width: "100%",
padding: "25px",
padding: "25px",
maxWidth: '750px'
}}
>
<ListOfJoinRequests show={show} setOpenSnack={setOpenSnack} setInfoSnack={setInfoSnack} groupId={selectedGroup?.groupId} />

View File

@@ -1,35 +1,46 @@
import * as React from 'react';
import { BottomNavigation, BottomNavigationAction, Typography } from '@mui/material';
import { Home, Groups, Message, ShowChart } from '@mui/icons-material';
import Box from '@mui/material/Box';
import BottomLogo from '../../assets/svgs/BottomLogo5.svg'
import { CustomSvg } from '../../common/CustomSvg';
import { WalletIcon } from '../../assets/Icons/WalletIcon';
import { HubsIcon } from '../../assets/Icons/HubsIcon';
import { TradingIcon } from '../../assets/Icons/TradingIcon';
import { MessagingIcon } from '../../assets/Icons/MessagingIcon';
import * as React from "react";
import {
BottomNavigation,
BottomNavigationAction,
Typography,
} from "@mui/material";
import { Home, Groups, Message, ShowChart } from "@mui/icons-material";
import Box from "@mui/material/Box";
import BottomLogo from "../../assets/svgs/BottomLogo5.svg";
import { CustomSvg } from "../../common/CustomSvg";
import { WalletIcon } from "../../assets/Icons/WalletIcon";
import { HubsIcon } from "../../assets/Icons/HubsIcon";
import { TradingIcon } from "../../assets/Icons/TradingIcon";
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
const IconWrapper = ({children, label, color})=> {
return <Box sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
gap: '5px',
flexDirection: 'column'
}}>
{children}
<Typography sx={{
fontFamily: "Inter",
fontSize: "12px",
fontWeight: 500,
color: color
}}>{label}</Typography>
const IconWrapper = ({ children, label, color }) => {
return (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "5px",
flexDirection: "column",
}}
>
{children}
<Typography
sx={{
fontFamily: "Inter",
fontSize: "12px",
fontWeight: 500,
color: color,
}}
>
{label}
</Typography>
</Box>
}
);
};
export const MobileFooter =({
selectedGroup,
export const MobileFooter = ({
selectedGroup,
groupSection,
isUnread,
goToAnnouncements,
@@ -44,84 +55,131 @@ selectedGroup,
openDrawerGroups,
goToHome,
setIsOpenDrawerProfile,
mobileViewMode,
mobileViewMode,
setMobileViewMode,
setMobileViewModeKeepOpen
setMobileViewModeKeepOpen,
hasUnreadGroups,
hasUnreadDirects
}) => {
const [value, setValue] = React.useState(0);
return (
<Box sx={{
width: '100%',
position: 'fixed',
bottom: 0,
backgroundColor: 'var(--bg-primary)',
display: 'flex',
alignItems: 'center',
height: '67px', // Footer height
const [value, setValue] = React.useState(0);
return (
<Box
sx={{
width: "100%",
position: "fixed",
bottom: 0,
backgroundColor: "var(--bg-primary)",
display: "flex",
alignItems: "center",
height: "67px", // Footer height
zIndex: 1,
borderTopRightRadius: '25px',
borderTopLeftRadius: '25px'
}}>
<BottomNavigation
showLabels
value={value}
onChange={(event, newValue) => setValue(newValue)}
sx={{ backgroundColor: 'transparent', flexGrow: 1 }}
>
<BottomNavigationAction onClick={()=> {
borderTopRightRadius: "25px",
borderTopLeftRadius: "25px",
boxShadow: '0px -2px 10px rgba(0, 0, 0, 0.1)',
}}
>
<BottomNavigation
showLabels
value={value}
onChange={(event, newValue) => setValue(newValue)}
sx={{ backgroundColor: "transparent", flexGrow: 1 }}
>
<BottomNavigationAction
onClick={() => {
// setMobileViewMode('wallet')
setIsOpenDrawerProfile(true)
}} icon={<IconWrapper color="rgba(250, 250, 250, 0.5)" label="Wallet"><WalletIcon color="rgba(250, 250, 250, 0.5)" /></IconWrapper>} sx={{ color: value === 0 ? 'white' : 'gray', padding: '0px 10px' }} />
<BottomNavigationAction onClick={()=> {
setMobileViewMode('groups')
}} icon={<IconWrapper color="rgba(250, 250, 250, 0.5)" label="Hubs"><HubsIcon color="rgba(250, 250, 250, 0.5)" /></IconWrapper>} sx={{ color: value === 0 ? 'white' : 'gray', paddingLeft: '10px', paddingRight: '42px' }} />
setIsOpenDrawerProfile(true);
}}
icon={
<IconWrapper color="rgba(250, 250, 250, 0.5)" label="Wallet">
<WalletIcon color="rgba(250, 250, 250, 0.5)" />
</IconWrapper>
}
sx={{ color: value === 0 ? "white" : "gray", padding: "0px 10px" }}
/>
<BottomNavigationAction
onClick={() => {
setMobileViewMode("groups");
}}
icon={
<IconWrapper color="rgba(250, 250, 250, 0.5)" label="Hubs">
<HubsIcon color={hasUnreadGroups ? "var(--unread)" : "rgba(250, 250, 250, 0.5)"} />
</IconWrapper>
}
sx={{
color: value === 0 ? "white" : "gray",
paddingLeft: "10px",
paddingRight: "42px",
}}
/>
</BottomNavigation>
</BottomNavigation>
{/* Floating Center Button */}
<Box sx={{
position: 'absolute',
bottom: '34px', // Adjusted to float properly based on footer height
left: '50%',
transform: 'translateX(-50%)', // Center horizontally
width: '59px',
height: '59px',
backgroundColor: 'var(--bg-primary)',
borderRadius: '50%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
boxShadow: '0 4px 10px rgba(0, 0, 0, 0.3)', // Subtle shadow for the floating effect
zIndex: 3,
}}>
<Box sx={{
width: '49px', // Slightly smaller inner circle
height: '49px',
backgroundColor: 'var(--bg-primary)',
borderRadius: '50%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
{/* Custom Center Icon */}
<img src={BottomLogo} alt="center-icon" />
</Box>
</Box>
<BottomNavigation
showLabels
value={value}
onChange={(event, newValue) => setValue(newValue)}
sx={{ backgroundColor: 'transparent', flexGrow: 1 }}
{/* Floating Center Button */}
<Box
sx={{
position: "absolute",
bottom: "34px", // Adjusted to float properly based on footer height
left: "50%",
transform: "translateX(-50%)", // Center horizontally
width: "59px",
height: "59px",
backgroundColor: "var(--bg-primary)",
borderRadius: "50%",
display: "flex",
justifyContent: "center",
alignItems: "center",
boxShadow: "0 4px 10px rgba(0, 0, 0, 0.3)", // Subtle shadow for the floating effect
zIndex: 3,
}}
>
<Box
sx={{
width: "49px", // Slightly smaller inner circle
height: "49px",
backgroundColor: "var(--bg-primary)",
borderRadius: "50%",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<BottomNavigationAction onClick={()=> {
setMobileViewModeKeepOpen('messaging')
}} icon={<IconWrapper label="Messaging" color="rgba(250, 250, 250, 0.5)"><MessagingIcon color="rgba(250, 250, 250, 0.5)" /></IconWrapper>} sx={{ color: value === 2 ? 'white' : 'gray', paddingLeft: '55px', paddingRight: '10px' }} />
<BottomNavigationAction onClick={() => {
chrome.tabs.create({ url: "https://www.qort.trade", active: true });
}} icon={<IconWrapper label="Trading" color="rgba(250, 250, 250, 0.5)"><TradingIcon color="rgba(250, 250, 250, 0.5)" /></IconWrapper>} sx={{ color: value === 3 ? 'white' : 'gray' , padding: '0px 10px'}} />
</BottomNavigation>
{/* Custom Center Icon */}
<img src={BottomLogo} alt="center-icon" />
</Box>
</Box>
);
}
<BottomNavigation
showLabels
value={value}
onChange={(event, newValue) => setValue(newValue)}
sx={{ backgroundColor: "transparent", flexGrow: 1 }}
>
<BottomNavigationAction
onClick={() => {
setMobileViewModeKeepOpen("messaging");
}}
icon={
<IconWrapper label="Messaging" color="rgba(250, 250, 250, 0.5)">
<MessagingIcon color={hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"} />
</IconWrapper>
}
sx={{
color: value === 2 ? "white" : "gray",
paddingLeft: "55px",
paddingRight: "10px",
}}
/>
<BottomNavigationAction
onClick={() => {
chrome.tabs.create({ url: "https://www.qort.trade", active: true });
}}
icon={
<IconWrapper label="Trading" color="rgba(250, 250, 250, 0.5)">
<TradingIcon color="rgba(250, 250, 250, 0.5)" />
</IconWrapper>
}
sx={{ color: value === 3 ? "white" : "gray", padding: "0px 10px" }}
/>
</BottomNavigation>
</Box>
);
};

View File

@@ -1,17 +1,35 @@
import React from 'react';
import { AppBar, Toolbar, IconButton, Typography, Box, MenuItem, Select, ButtonBase } from '@mui/material';
import { HomeIcon } from '../../assets/Icons/HomeIcon';
import { LogoutIcon } from '../../assets/Icons/LogoutIcon';
import { NotificationIcon } from '../../assets/Icons/NotificationIcon';
import { ArrowDownIcon } from '../../assets/Icons/ArrowDownIcon';
import { MessagingIcon } from '../../assets/Icons/MessagingIcon';
import React, { useState } from "react";
import {
AppBar,
Toolbar,
IconButton,
Typography,
Box,
MenuItem,
Select,
ButtonBase,
Menu,
ListItemIcon,
ListItemText,
} from "@mui/material";
import { HomeIcon } from "../../assets/Icons/HomeIcon";
import { LogoutIcon } from "../../assets/Icons/LogoutIcon";
import { NotificationIcon } from "../../assets/Icons/NotificationIcon";
import { ArrowDownIcon } from "../../assets/Icons/ArrowDownIcon";
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2";
import { HubsIcon } from "../../assets/Icons/HubsIcon";
const Header = ({
logoutFunc,
goToHome,
setIsOpenDrawerProfile,
isThin,
setMobileViewModeKeepOpen
setMobileViewModeKeepOpen,
hasUnreadGroups,
hasUnreadDirects,
setMobileViewMode,
// selectedGroup,
// onHomeClick,
// onLogoutClick,
@@ -19,94 +37,243 @@ const Header = ({
// onWalletClick,
// onNotificationClick,
}) => {
if(isThin){
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
if (isThin) {
return (
<AppBar position="static" sx={{ backgroundColor: 'background: rgba(0, 0, 0, 0.2)', boxShadow: 'none' }}>
<Toolbar sx={{ justifyContent: 'space-between', padding: '0 16px', height: '30px', minHeight: '30px' }}>
{/* Left Home Icon */}
<Box sx={{
display: 'flex',
alignItems: 'center',
gap: '18px',
width: '75px'
}}>
<IconButton edge="start" color="inherit" aria-label="home"
onClick={()=> {
setMobileViewModeKeepOpen('')
goToHome()
}}
// onClick={onHomeClick}
<AppBar
position="static"
sx={{
backgroundColor: "background: rgba(0, 0, 0, 0.2)",
boxShadow: "none",
}}
>
<Toolbar
sx={{
justifyContent: "space-between",
padding: "0 16px",
height: "45px",
minHeight: "45px",
}}
>
<HomeIcon height={16} width={18} color="rgba(145, 145, 147, 1)" />
</IconButton>
<IconButton edge="start" color="inherit" aria-label="home"
onClick={()=> {
setMobileViewModeKeepOpen()
goToHome()
}}
// onClick={onHomeClick}
{/* Left Home Icon */}
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "18px",
width: "75px",
}}
>
<IconButton
edge="start"
color="inherit"
aria-label="home"
onClick={() => {
setMobileViewModeKeepOpen("");
goToHome();
}}
// onClick={onHomeClick}
>
<HomeIcon height={20} width={27} color="rgba(145, 145, 147, 1)" />
</IconButton>
<IconButton
edge="start"
color="inherit"
aria-label="home"
onClick={handleClick}
>
<NotificationIcon height={20} width={21} color={hasUnreadDirects || hasUnreadGroups ? "var(--unread)" : "rgba(145, 145, 147, 1)"} />
</IconButton>
</Box>
{/* Center Title */}
<Typography
variant="h6"
sx={{
color: "rgba(255, 255, 255, 1)",
fontWeight: 700,
letterSpacing: "2px",
fontSize: "13px",
}}
>
QORTAL
</Typography>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "18px",
width: "75px",
justifyContent: "flex-end",
}}
>
{/* Right Logout Icon */}
<IconButton
onClick={() => {
setMobileViewModeKeepOpen("messaging");
}}
edge="end"
color="inherit"
aria-label="logout"
// onClick={onLogoutClick}
>
<MessagingIcon2 height={20} color={hasUnreadDirects ? "var(--unread)" : "rgba(145, 145, 147, 1)"}
/>
</IconButton>
<IconButton
onClick={logoutFunc}
edge="end"
color="inherit"
aria-label="logout"
// onClick={onLogoutClick}
>
<LogoutIcon
height={20}
width={21}
color="rgba(145, 145, 147, 1)"
/>
</IconButton>
</Box>
</Toolbar>
<Menu
id="home-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button",
}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
slotProps={{
paper: {
sx: {
backgroundColor: 'var(--bg-primary)',
color: '#fff',
width: '148px',
borderRadius: '5px'
},
},
}}
sx={{
marginTop: '10px'
}}
>
<MenuItem
onClick={() => {
setMobileViewMode("groups");
setMobileViewModeKeepOpen("")
handleClose();
}}
>
<NotificationIcon color="rgba(145, 145, 147, 1)" />
</IconButton>
</Box>
<ListItemIcon sx={{
minWidth: '24px !important'
}}>
<HubsIcon height={20} color={hasUnreadGroups ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"} />
</ListItemIcon>
<ListItemText sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"
},
}} primary="Hubs" />
</MenuItem>
<MenuItem
onClick={() => {
setMobileViewModeKeepOpen("messaging");
{/* Center Title */}
<Typography variant="h6" sx={{ color: 'rgba(255, 255, 255, 1)', fontWeight: 700, letterSpacing: '2px' , fontSize: '13px'}}>
QORTAL
</Typography>
<Box sx={{
display: 'flex',
alignItems: 'center',
gap: '18px',
width: '75px',
justifyContent: 'flex-end'
}}>
{/* Right Logout Icon */}
<IconButton onClick={()=> {
setMobileViewModeKeepOpen('messaging')
}} edge="end" color="inherit" aria-label="logout"
// onClick={onLogoutClick}
>
<MessagingIcon height={16} width={16} color="rgba(145, 145, 147, 1)" />
</IconButton>
<IconButton onClick={logoutFunc} edge="end" color="inherit" aria-label="logout"
// onClick={onLogoutClick}
handleClose();
}}
>
<LogoutIcon height={16} width={14} color="rgba(145, 145, 147, 1)" />
</IconButton>
</Box>
</Toolbar>
</AppBar>
)
<ListItemIcon sx={{
minWidth: '24px !important'
}}>
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"} />
</ListItemIcon>
<ListItemText sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"
},
}} primary="Messaging" />
</MenuItem>
</Menu>
</AppBar>
);
}
return (
<>
{/* Main Header */}
<AppBar position="static" sx={{ backgroundColor: 'var(--bg-primary)', boxShadow: 'none' }}>
<Toolbar sx={{ justifyContent: 'space-between', padding: '0 16px', height: '60px' }}>
<AppBar
position="static"
sx={{ backgroundColor: "var(--bg-primary)", boxShadow: "none" }}
>
<Toolbar
sx={{
justifyContent: "space-between",
padding: "0 16px",
height: "60px",
}}
>
{/* Left Home Icon */}
<IconButton edge="start" color="inherit" aria-label="home"
onClick={goToHome}
// onClick={onHomeClick}
<IconButton
edge="start"
color="inherit"
aria-label="home"
onClick={goToHome}
// onClick={onHomeClick}
>
<HomeIcon color="rgba(145, 145, 147, 1)" />
<HomeIcon color="rgba(145, 145, 147, 1)" />
</IconButton>
{/* Center Title */}
<Typography variant="h6" sx={{ color: 'rgba(255, 255, 255, 1)', fontWeight: 700, letterSpacing: '2px' , fontSize: '13px'}}>
<Typography
variant="h6"
sx={{
color: "rgba(255, 255, 255, 1)",
fontWeight: 700,
letterSpacing: "2px",
fontSize: "13px",
}}
>
QORTAL
</Typography>
{/* Right Logout Icon */}
<IconButton onClick={logoutFunc} edge="end" color="inherit" aria-label="logout"
<IconButton
onClick={logoutFunc}
edge="end"
color="inherit"
aria-label="logout"
// onClick={onLogoutClick}
// onClick={onLogoutClick}
>
<LogoutIcon color="rgba(145, 145, 147, 1)" />
</IconButton>
@@ -116,69 +283,160 @@ onClick={()=> {
{/* Secondary Section */}
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: 'var(--bg-3)',
padding: '8px 16px',
position: 'relative',
height: '27px'
display: "flex",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "var(--bg-3)",
padding: "8px 16px",
position: "relative",
height: "27px",
}}
>
<Box sx={{
display: 'flex',
gap: '10px',
alignItems: 'center',
userSelect: 'none'
}}>
<Typography sx={{ color: 'rgba(255, 255, 255, 1)', fontWeight: 400, fontSize: '11px'}}>
<Box
sx={{
display: "flex",
gap: "10px",
alignItems: "center",
userSelect: "none",
}}
>
<Typography
sx={{
color: "rgba(255, 255, 255, 1)",
fontWeight: 400,
fontSize: "11px",
}}
>
Palmas
</Typography>
{/*
{/*
<ArrowDownIcon /> */}
</Box>
<Box
sx={{
position: 'absolute',
left: '50%',
transform: 'translate(-50%, 50%)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
position: "absolute",
left: "50%",
transform: "translate(-50%, 50%)",
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: 500,
width: '30px', // Adjust as needed
height: '30px', // Adjust as needed
backgroundColor: '#232428', // Circle background
borderRadius: '50%',
boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.3)', // Optional shadow for the circle
width: "30px", // Adjust as needed
height: "30px", // Adjust as needed
backgroundColor: "#232428", // Circle background
borderRadius: "50%",
boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.3)", // Optional shadow for the circle
}}
>
<IconButton color="inherit">
<NotificationIcon color="rgba(255, 255, 255, 1)" />
<IconButton onClick={handleClick} color="inherit">
<NotificationIcon color={hasUnreadDirects || hasUnreadGroups ? "var(--unread)" : "rgba(255, 255, 255, 1)"} />
</IconButton>
</Box>
{/* Right Dropdown */}
<ButtonBase onClick={()=> {
setIsOpenDrawerProfile(true)
}}>
<Box sx={{
display: 'flex',
gap: '10px',
alignItems: 'center'
}}>
<Typography sx={{ color: 'rgba(255, 255, 255, 1)', fontWeight: 400, fontSize: '11px'}}>
View Wallet
</Typography>
{/* <ButtonBase
onClick={() => {
setIsOpenDrawerProfile(true);
}}
>
<Box
sx={{
display: "flex",
gap: "10px",
alignItems: "center",
}}
>
<Typography
sx={{
color: "rgba(255, 255, 255, 1)",
fontWeight: 400,
fontSize: "11px",
}}
>
View Wallet
</Typography>
<ArrowDownIcon />
</Box>
</ButtonBase>
<ArrowDownIcon />
</Box>
</ButtonBase> */}
</Box>
<Menu
id="home-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button",
}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
slotProps={{
paper: {
sx: {
backgroundColor: 'var(--bg-primary)',
color: '#fff',
width: '148px',
borderRadius: '5px'
},
},
}}
sx={{
marginTop: '10px'
}}
>
<MenuItem
onClick={() => {
setMobileViewMode("groups");
setMobileViewModeKeepOpen("")
handleClose();
}}
>
<ListItemIcon sx={{
minWidth: '24px !important'
}}>
<HubsIcon height={20} color={hasUnreadGroups ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"} />
</ListItemIcon>
<ListItemText sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"
},
}} primary="Hubs" />
</MenuItem>
<MenuItem
onClick={() => {
setMobileViewModeKeepOpen("messaging");
handleClose();
}}
>
<ListItemIcon sx={{
minWidth: '24px !important'
}}>
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"} />
</ListItemIcon>
<ListItemText sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadDirects ? "var(--unread)" :"rgba(250, 250, 250, 0.5)"
},
}} primary="Messaging" />
</MenuItem>
</Menu>
</>
);
};