added tabs

This commit is contained in:
PhilReact 2024-10-18 04:51:16 +03:00
parent 28c2dfbb7a
commit 54b1725585
6 changed files with 243 additions and 25 deletions

View File

@ -3,7 +3,7 @@ import { AppViewer } from './AppViewer'
import Frame from 'react-frame-component'; import Frame from 'react-frame-component';
import { MyContext } from '../../App'; import { MyContext } from '../../App';
const AppViewerContainer = ({app, isSelected}) => { const AppViewerContainer = ({app, isSelected, hide}) => {
const { rootHeight } = useContext(MyContext); const { rootHeight } = useContext(MyContext);
const frameRef = useRef(null); const frameRef = useRef(null);
@ -32,7 +32,7 @@ const AppViewerContainer = ({app, isSelected}) => {
height: `calc(${rootHeight} - 60px - 45px)`, height: `calc(${rootHeight} - 60px - 45px)`,
border: 'none', border: 'none',
width: '100%', width: '100%',
display: !isSelected && 'none' display: (!isSelected || hide) && 'none'
}} ><AppViewer app={app} /></Frame> }} ><AppViewer app={app} /></Frame>
) )
} }

View File

@ -186,9 +186,23 @@ import {
display: "flex", display: "flex",
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
flexGrow: 1
})); }));
export const AppsNavBarRight = styled(Box)(({ theme }) => ({ export const AppsNavBarRight = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
justifyContent: 'flex-end', justifyContent: 'flex-end',
alignItems: 'center', alignItems: 'center',
})); }));
export const TabParent = styled(Box)(({ theme }) => ({
height: '36px',
width: '36px',
backgroundColor: '#434343',
position: 'relative',
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}));

View File

@ -4,7 +4,7 @@ import { Spacer } from '../../common/Spacer'
import { MyContext, getBaseApiReact } from '../../App' import { MyContext, getBaseApiReact } from '../../App'
import { AppsLibrary } from './AppsLibrary' import { AppsLibrary } from './AppsLibrary'
import { AppInfo } from './AppInfo' import { AppInfo } from './AppInfo'
import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events' import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from '../../utils/events'
import { AppsNavBar } from './AppsNavBar' import { AppsNavBar } from './AppsNavBar'
import { AppsParent } from './Apps-styles' import { AppsParent } from './Apps-styles'
import { AppViewer } from './AppViewer' import { AppViewer } from './AppViewer'
@ -14,13 +14,24 @@ import ShortUniqueId from "short-unique-id";
const uid = new ShortUniqueId({ length: 8 }); const uid = new ShortUniqueId({ length: 8 });
export const Apps = ({mode, setMode}) => { export const Apps = ({mode, setMode, show}) => {
const [availableQapps, setAvailableQapps] = useState([]) const [availableQapps, setAvailableQapps] = useState([])
const [downloadedQapps, setDownloadedQapps] = useState([]) const [downloadedQapps, setDownloadedQapps] = useState([])
const [selectedAppInfo, setSelectedAppInfo] = useState(null) const [selectedAppInfo, setSelectedAppInfo] = useState(null)
const [tabs, setTabs] = useState([]) const [tabs, setTabs] = useState([])
const [selectedTab, setSelectedTab] = useState(null) 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( const getQapps = React.useCallback(
async () => { async () => {
@ -85,8 +96,8 @@ export const Apps = ({mode, setMode}) => {
} else if(mode === 'library'){ } else if(mode === 'library'){
setMode('home') setMode('home')
} else { } else {
const iframeId = `browser-iframe-${selectedTab?.tabId}`
const iframe = document.getElementById('browser-iframe2'); const iframe = document.getElementById(iframeId);
console.log('iframe', iframe) console.log('iframe', iframe)
// Go Back in the iframe's history // Go Back in the iframe's history
if (iframe) { if (iframe) {
@ -108,7 +119,7 @@ if (iframe) {
return () => { return () => {
unsubscribeFromEvent("navigateBack", navigateBackFunc); unsubscribeFromEvent("navigateBack", navigateBackFunc);
}; };
}, [mode]); }, [mode, selectedTab]);
const addTabFunc = (e) => { const addTabFunc = (e) => {
@ -119,6 +130,9 @@ if (iframe) {
} }
setTabs((prev)=> [...prev, newTab]) setTabs((prev)=> [...prev, newTab])
setSelectedTab(newTab) setSelectedTab(newTab)
setMode('viewer')
setIsNewTabWindow(false)
}; };
useEffect(() => { useEffect(() => {
@ -127,10 +141,76 @@ if (iframe) {
return () => { return () => {
unsubscribeFromEvent("addTab", addTabFunc); 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 ( return (
<AppsParent> <AppsParent>
@ -141,14 +221,14 @@ if (iframe) {
{mode === 'home' && <AppsHome downloadedQapps={downloadedQapps} setMode={setMode} />} {mode === 'home' && <AppsHome downloadedQapps={downloadedQapps} setMode={setMode} />}
{mode === 'library' && <AppsLibrary downloadedQapps={downloadedQapps} availableQapps={availableQapps} />} {mode === 'library' && <AppsLibrary downloadedQapps={downloadedQapps} availableQapps={availableQapps} />}
{mode === 'appInfo' && <AppInfo app={selectedAppInfo} />} {mode === 'appInfo' && <AppInfo app={selectedAppInfo} />}
{mode === 'viewer' && (
<>
{tabs.map((tab)=> { {tabs.map((tab)=> {
return <AppViewerContainer isSelected={tab?.tabId === selectedTab?.tabId} app={tab} /> return <AppViewerContainer hide={isNewTabWindow} isSelected={tab?.tabId === selectedTab?.tabId} app={tab} />
})} })}
</>
) } {isNewTabWindow && (
<AppsHome downloadedQapps={downloadedQapps} setMode={setMode} />
)}
{mode !== 'viewer' && ( {mode !== 'viewer' && (
<Spacer height="180px" /> <Spacer height="180px" />

View File

@ -1,17 +1,48 @@
import React from "react"; import React, { useEffect, useRef, useState } from "react";
import { import {
AppsNavBarLeft, AppsNavBarLeft,
AppsNavBarParent, AppsNavBarParent,
AppsNavBarRight, AppsNavBarRight,
} from "./Apps-styles"; } from "./Apps-styles";
import NavBack from "../../assets/svgs/NavBack.svg"; import NavBack from "../../assets/svgs/NavBack.svg";
import NavCloseTab from "../../assets/svgs/NavCloseTab.svg";
import NavAdd from "../../assets/svgs/NavAdd.svg"; import NavAdd from "../../assets/svgs/NavAdd.svg";
import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg"; import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg";
import { ButtonBase } from "@mui/material"; import { ButtonBase, Tab, Tabs } from "@mui/material";
import { executeEvent } from "../../utils/events"; import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
import TabComponent from "./TabComponent";
export const AppsNavBar = () => { 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 ( return (
<AppsNavBarParent> <AppsNavBarParent>
<AppsNavBarLeft> <AppsNavBarLeft>
@ -21,11 +52,43 @@ export const AppsNavBar = () => {
}}> }}>
<img src={NavBack} /> <img src={NavBack} />
</ButtonBase> </ButtonBase>
<Tabs
ref={tabsRef}
aria-label="basic tabs example"
variant="scrollable" // Make tabs scrollable
scrollButtons={false}
sx={{
"& .MuiTabs-indicator": {
backgroundColor: "white",
},
maxWidth: `calc(100vw - 150px)`, // Ensure the tabs container fits within the available space
overflow: 'hidden', // Prevents overflow on small screens
}}
>
{tabs?.map((tab) => (
<Tab
key={tab.tabId}
label={<TabComponent isSelected={tab?.tabId === selectedTab?.tabId} app={tab} />} // Pass custom component
sx={{
"&.Mui-selected": {
color: "white",
},
padding: '0px',
margin: '0px',
minWidth: '0px',
width: '50px'
}}
/>
))}
</Tabs>
</AppsNavBarLeft> </AppsNavBarLeft>
<AppsNavBarRight sx={{ <AppsNavBarRight sx={{
gap: '10px' gap: '10px'
}}> }}>
<ButtonBase> <ButtonBase onClick={()=> {
executeEvent("newTabWindow", {
});
}}>
<img style={{ <img style={{
height: '40px', height: '40px',
width: '40px' width: '40px'

View File

@ -0,0 +1,61 @@
import React from 'react'
import { TabParent } from './Apps-styles'
import NavCloseTab from "../../assets/svgs/NavCloseTab.svg";
import { getBaseApiReact } from '../../App';
import { Avatar, ButtonBase } from '@mui/material';
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from '../../utils/events';
const TabComponent = ({isSelected, app}) => {
return (
<ButtonBase onClick={()=> {
if(isSelected){
executeEvent('removeTab', {
data: app
})
return
}
executeEvent('setSelectedTab', {
data: app
})
}}>
<TabParent sx={{
border: isSelected && '1px solid #FFFFFF'
}}>
{isSelected && (
<img style={
{
position: 'absolute',
top: '-5px',
right: '-5px',
zIndex: 1
}
} src={NavCloseTab}/>
) }
<Avatar
sx={{
height: "31px",
width: "31px",
}}
alt={app?.name}
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
app?.name
}/qortal_avatar?async=true`}
>
<img
style={{
width: "31px",
height: "auto",
}}
src={LogoSelected}
alt="center-icon"
/>
</Avatar>
</TabParent>
</ButtonBase>
)
}
export default TabComponent

View File

@ -433,7 +433,7 @@ export const Group = ({
const { clearStatesMessageQueueProvider } = useMessageQueue(); const { clearStatesMessageQueueProvider } = useMessageQueue();
const initiatedGetMembers = useRef(false); const initiatedGetMembers = useRef(false);
const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({}); const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({});
const [appsMode, setAppsMode] = useState('viewer') const [appsMode, setAppsMode] = useState('home')
useEffect(()=> { useEffect(()=> {
timestampEnterDataRef.current = timestampEnterData timestampEnterDataRef.current = timestampEnterData
@ -2736,8 +2736,8 @@ export const Group = ({
setMobileViewMode={setMobileViewMode} setMobileViewMode={setMobileViewMode}
/> />
)} )}
{isMobile && mobileViewMode === "apps" && ( {isMobile && (
<Apps mode={appsMode} setMode={setAppsMode} /> <Apps mode={appsMode} setMode={setAppsMode} show={mobileViewMode === "apps"} />
)} )}
{ {
!isMobile && !selectedGroup && !isMobile && !selectedGroup &&