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 { 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'
}} ><AppViewer app={app} /></Frame>
)
}

View File

@ -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',
}));
}));
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 { 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 (
<AppsParent>
@ -141,14 +221,14 @@ if (iframe) {
{mode === 'home' && <AppsHome downloadedQapps={downloadedQapps} setMode={setMode} />}
{mode === 'library' && <AppsLibrary downloadedQapps={downloadedQapps} availableQapps={availableQapps} />}
{mode === 'appInfo' && <AppInfo app={selectedAppInfo} />}
{mode === 'viewer' && (
<>
{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' && (
<Spacer height="180px" />

View File

@ -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 (
<AppsNavBarParent>
<AppsNavBarLeft>
@ -21,11 +52,43 @@ export const AppsNavBar = () => {
}}>
<img src={NavBack} />
</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>
<AppsNavBarRight sx={{
gap: '10px'
}}>
<ButtonBase>
<ButtonBase onClick={()=> {
executeEvent("newTabWindow", {
});
}}>
<img style={{
height: '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 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" && (
<Apps mode={appsMode} setMode={setAppsMode} />
{isMobile && (
<Apps mode={appsMode} setMode={setAppsMode} show={mobileViewMode === "apps"} />
)}
{
!isMobile && !selectedGroup &&