diff --git a/src/components/Apps/AppViewerContainer.tsx b/src/components/Apps/AppViewerContainer.tsx index ef04760..c566ee4 100644 --- a/src/components/Apps/AppViewerContainer.tsx +++ b/src/components/Apps/AppViewerContainer.tsx @@ -3,7 +3,7 @@ import { AppViewer } from './AppViewer' import Frame from 'react-frame-component'; import { MyContext } from '../../App'; -const AppViewerContainer = ({app, isSelected}) => { +const AppViewerContainer = ({app, isSelected, hide}) => { const { rootHeight } = useContext(MyContext); const frameRef = useRef(null); @@ -32,7 +32,7 @@ const AppViewerContainer = ({app, isSelected}) => { height: `calc(${rootHeight} - 60px - 45px)`, border: 'none', width: '100%', - display: !isSelected && 'none' + display: (!isSelected || hide) && 'none' }} > ) } diff --git a/src/components/Apps/Apps-styles.tsx b/src/components/Apps/Apps-styles.tsx index 6f67658..d219bcb 100644 --- a/src/components/Apps/Apps-styles.tsx +++ b/src/components/Apps/Apps-styles.tsx @@ -186,9 +186,23 @@ import { display: "flex", justifyContent: 'flex-start', alignItems: 'center', + flexGrow: 1 })); export const AppsNavBarRight = styled(Box)(({ theme }) => ({ display: "flex", justifyContent: 'flex-end', alignItems: 'center', - })); \ No newline at end of file + })); + + export const TabParent = styled(Box)(({ theme }) => ({ + height: '36px', + width: '36px', + backgroundColor: '#434343', + position: 'relative', + borderRadius: '50%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + })); + + \ No newline at end of file diff --git a/src/components/Apps/Apps.tsx b/src/components/Apps/Apps.tsx index 0f4a1f0..79684c2 100644 --- a/src/components/Apps/Apps.tsx +++ b/src/components/Apps/Apps.tsx @@ -4,7 +4,7 @@ import { Spacer } from '../../common/Spacer' import { MyContext, getBaseApiReact } from '../../App' import { AppsLibrary } from './AppsLibrary' import { AppInfo } from './AppInfo' -import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events' +import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from '../../utils/events' import { AppsNavBar } from './AppsNavBar' import { AppsParent } from './Apps-styles' import { AppViewer } from './AppViewer' @@ -14,13 +14,24 @@ import ShortUniqueId from "short-unique-id"; const uid = new ShortUniqueId({ length: 8 }); -export const Apps = ({mode, setMode}) => { +export const Apps = ({mode, setMode, show}) => { const [availableQapps, setAvailableQapps] = useState([]) const [downloadedQapps, setDownloadedQapps] = useState([]) const [selectedAppInfo, setSelectedAppInfo] = useState(null) const [tabs, setTabs] = useState([]) const [selectedTab, setSelectedTab] = useState(null) - + const [isNewTabWindow, setIsNewTabWindow] = useState(false) + + useEffect(()=> { + setTimeout(() => { + executeEvent('setTabsToNav', { + data: { + tabs: tabs, + selectedTab: selectedTab + } + }) + }, 100); + }, [show, tabs, selectedTab]) const getQapps = React.useCallback( async () => { @@ -85,8 +96,8 @@ export const Apps = ({mode, setMode}) => { } else if(mode === 'library'){ setMode('home') } else { - - const iframe = document.getElementById('browser-iframe2'); + const iframeId = `browser-iframe-${selectedTab?.tabId}` + const iframe = document.getElementById(iframeId); console.log('iframe', iframe) // Go Back in the iframe's history if (iframe) { @@ -108,7 +119,7 @@ if (iframe) { return () => { unsubscribeFromEvent("navigateBack", navigateBackFunc); }; - }, [mode]); + }, [mode, selectedTab]); const addTabFunc = (e) => { @@ -119,6 +130,9 @@ if (iframe) { } setTabs((prev)=> [...prev, newTab]) setSelectedTab(newTab) + setMode('viewer') + + setIsNewTabWindow(false) }; useEffect(() => { @@ -127,10 +141,76 @@ if (iframe) { return () => { unsubscribeFromEvent("addTab", addTabFunc); }; - }, [mode]); - + }, [tabs]); + const setSelectedTabFunc = (e) => { + const data = e.detail?.data; + + + setSelectedTab(data) + setTimeout(() => { + executeEvent('setTabsToNav', { + data: { + tabs: tabs, + selectedTab: data + } + }) + }, 100); + setIsNewTabWindow(false) + }; + useEffect(() => { + subscribeToEvent("setSelectedTab", setSelectedTabFunc); + + return () => { + unsubscribeFromEvent("setSelectedTab", setSelectedTabFunc); + }; + }, [tabs]); + + const removeTabFunc = (e) => { + const data = e.detail?.data; + const copyTabs = [...tabs].filter((tab)=> tab?.tabId !== data?.tabId) + if(copyTabs?.length === 0){ + setMode('home') + } + else{ + setSelectedTab(copyTabs[0]) + } + setTabs(copyTabs) + setSelectedTab(copyTabs[0]) + setTimeout(() => { + executeEvent('setTabsToNav', { + data: { + tabs: copyTabs, + selectedTab: copyTabs[0] + } + }) + }, 400); + + }; + + useEffect(() => { + subscribeToEvent("removeTab", removeTabFunc); + + return () => { + unsubscribeFromEvent("removeTab", removeTabFunc); + }; + }, [tabs]); + + const setNewTabWindowFunc = (e) => { + setIsNewTabWindow(true) + + }; + + useEffect(() => { + subscribeToEvent("newTabWindow", setNewTabWindowFunc); + + return () => { + unsubscribeFromEvent("newTabWindow", setNewTabWindowFunc); + }; + }, [tabs]); + + if(!show) return null return ( @@ -141,14 +221,14 @@ if (iframe) { {mode === 'home' && } {mode === 'library' && } {mode === 'appInfo' && } - {mode === 'viewer' && ( - <> + {tabs.map((tab)=> { - return + return })} - - ) } - + + {isNewTabWindow && ( + + )} {mode !== 'viewer' && ( diff --git a/src/components/Apps/AppsNavBar.tsx b/src/components/Apps/AppsNavBar.tsx index 01dc0e6..2e1ec5c 100644 --- a/src/components/Apps/AppsNavBar.tsx +++ b/src/components/Apps/AppsNavBar.tsx @@ -1,17 +1,48 @@ -import React from "react"; +import React, { useEffect, useRef, useState } from "react"; import { AppsNavBarLeft, AppsNavBarParent, AppsNavBarRight, } from "./Apps-styles"; import NavBack from "../../assets/svgs/NavBack.svg"; -import NavCloseTab from "../../assets/svgs/NavCloseTab.svg"; import NavAdd from "../../assets/svgs/NavAdd.svg"; import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg"; -import { ButtonBase } from "@mui/material"; -import { executeEvent } from "../../utils/events"; +import { ButtonBase, Tab, Tabs } from "@mui/material"; +import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events"; +import TabComponent from "./TabComponent"; export const AppsNavBar = () => { + const [tabs, setTabs] = useState([]) + const [selectedTab, setSelectedTab] = useState([]) + + const tabsRef = useRef(null); + + useEffect(() => { + // Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added) + if (tabsRef.current) { + const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root'); + console.log('tabElements', tabElements) + if (tabElements.length > 0) { + const lastTab = tabElements[tabElements.length - 1]; + lastTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' }); + } + } + }, [tabs.length]); // Dependency on the number of tabs + + const setTabsToNav = (e) => { + const {tabs, selectedTab} = e.detail?.data; + + setTabs([...tabs]) + setSelectedTab({...selectedTab}) + }; + + useEffect(() => { + subscribeToEvent("setTabsToNav", setTabsToNav); + + return () => { + unsubscribeFromEvent("setTabsToNav", setTabsToNav); + }; + }, []); return ( @@ -21,11 +52,43 @@ export const AppsNavBar = () => { }}> + + {tabs?.map((tab) => ( + } // Pass custom component + sx={{ + "&.Mui-selected": { + color: "white", + }, + padding: '0px', + margin: '0px', + minWidth: '0px', + width: '50px' + }} + /> + ))} + - + { + executeEvent("newTabWindow", { + }); + }}> { + return ( + { + if(isSelected){ + executeEvent('removeTab', { + data: app + }) + return + } + executeEvent('setSelectedTab', { + data: app + }) + }}> + + {isSelected && ( + + + + ) } + + center-icon + + + + ) +} + +export default TabComponent \ No newline at end of file diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index 719ebe9..3a147b3 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -433,7 +433,7 @@ export const Group = ({ const { clearStatesMessageQueueProvider } = useMessageQueue(); const initiatedGetMembers = useRef(false); const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({}); - const [appsMode, setAppsMode] = useState('viewer') + const [appsMode, setAppsMode] = useState('home') useEffect(()=> { timestampEnterDataRef.current = timestampEnterData @@ -2736,8 +2736,8 @@ export const Group = ({ setMobileViewMode={setMobileViewMode} /> )} - {isMobile && mobileViewMode === "apps" && ( - + {isMobile && ( + )} { !isMobile && !selectedGroup &&