mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-14 12:01:21 +00:00
Format code
This commit is contained in:
parent
515379ab71
commit
6dea8e2468
@ -1,51 +1,34 @@
|
|||||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, 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.tsx';
|
||||||
import NavAdd from "../../assets/svgs/NavAdd.svg";
|
import { NavAdd } from '../../assets/svgs/NavAdd.tsx';
|
||||||
import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg";
|
import { ButtonBase, Tab, Tabs } from '@mui/material';
|
||||||
import {
|
|
||||||
ButtonBase,
|
|
||||||
ListItemIcon,
|
|
||||||
ListItemText,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
Tab,
|
|
||||||
Tabs,
|
|
||||||
} from "@mui/material";
|
|
||||||
import {
|
import {
|
||||||
executeEvent,
|
executeEvent,
|
||||||
subscribeToEvent,
|
subscribeToEvent,
|
||||||
unsubscribeFromEvent,
|
unsubscribeFromEvent,
|
||||||
} from "../../utils/events";
|
} from '../../utils/events';
|
||||||
import TabComponent from "./TabComponent";
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
import PushPinIcon from "@mui/icons-material/PushPin";
|
import { useRecoilState } from 'recoil';
|
||||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
import { navigationControllerAtom } from '../../atoms/global';
|
||||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
import { AppsDevModeTabComponent } from './AppsDevModeTabComponent';
|
||||||
import {
|
|
||||||
navigationControllerAtom,
|
|
||||||
settingsLocalLastUpdatedAtom,
|
|
||||||
sortablePinnedAppsAtom,
|
|
||||||
} from "../../atoms/global";
|
|
||||||
import { AppsDevModeTabComponent } from "./AppsDevModeTabComponent";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const AppsDevModeNavBar = () => {
|
export const AppsDevModeNavBar = () => {
|
||||||
const [tabs, setTabs] = useState([]);
|
const [tabs, setTabs] = useState([]);
|
||||||
const [selectedTab, setSelectedTab] = useState(null);
|
const [selectedTab, setSelectedTab] = useState(null);
|
||||||
const [navigationController, setNavigationController] = useRecoilState(navigationControllerAtom)
|
const [navigationController, setNavigationController] = useRecoilState(
|
||||||
|
navigationControllerAtom
|
||||||
|
);
|
||||||
|
|
||||||
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
|
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
|
||||||
const tabsRef = useRef(null);
|
const tabsRef = useRef(null);
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
@ -57,27 +40,25 @@ export const AppsDevModeNavBar = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
||||||
if (tabsRef.current) {
|
if (tabsRef.current) {
|
||||||
const tabElements = tabsRef.current.querySelectorAll(".MuiTab-root");
|
const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root');
|
||||||
if (tabElements.length > 0) {
|
if (tabElements.length > 0) {
|
||||||
const lastTab = tabElements[tabElements.length - 1];
|
const lastTab = tabElements[tabElements.length - 1];
|
||||||
lastTab.scrollIntoView({
|
lastTab.scrollIntoView({
|
||||||
behavior: "smooth",
|
behavior: 'smooth',
|
||||||
block: "nearest",
|
block: 'nearest',
|
||||||
inline: "end",
|
inline: 'end',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [tabs.length]); // Dependency on the number of tabs
|
}, [tabs.length]); // Dependency on the number of tabs
|
||||||
|
|
||||||
|
|
||||||
const isDisableBackButton = useMemo(() => {
|
const isDisableBackButton = useMemo(() => {
|
||||||
if(selectedTab && navigationController[selectedTab?.tabId]?.hasBack) return false
|
if (selectedTab && navigationController[selectedTab?.tabId]?.hasBack)
|
||||||
if(selectedTab && !navigationController[selectedTab?.tabId]?.hasBack) return true
|
return false;
|
||||||
return false
|
if (selectedTab && !navigationController[selectedTab?.tabId]?.hasBack)
|
||||||
}, [navigationController, selectedTab])
|
return true;
|
||||||
|
return false;
|
||||||
|
}, [navigationController, selectedTab]);
|
||||||
|
|
||||||
|
|
||||||
const setTabsToNav = (e) => {
|
const setTabsToNav = (e) => {
|
||||||
const { tabs, selectedTab, isNewTabWindow } = e.detail?.data;
|
const { tabs, selectedTab, isNewTabWindow } = e.detail?.data;
|
||||||
@ -88,45 +69,43 @@ export const AppsDevModeNavBar = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subscribeToEvent("appsDevModeSetTabsToNav", setTabsToNav);
|
subscribeToEvent('appsDevModeSetTabsToNav', setTabsToNav);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeFromEvent("appsDevModeSetTabsToNav", setTabsToNav);
|
unsubscribeFromEvent('appsDevModeSetTabsToNav', setTabsToNav);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppsNavBarParent
|
<AppsNavBarParent
|
||||||
sx={{
|
sx={{
|
||||||
position: "relative",
|
position: 'relative',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
width: "60px",
|
width: '60px',
|
||||||
height: "unset",
|
height: 'unset',
|
||||||
maxHeight: "70vh",
|
maxHeight: '70vh',
|
||||||
borderRadius: "0px 30px 30px 0px",
|
borderRadius: '0px 30px 30px 0px',
|
||||||
padding: "10px",
|
padding: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AppsNavBarLeft
|
<AppsNavBarLeft
|
||||||
sx={{
|
sx={{
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
executeEvent("devModeNavigateBack", selectedTab?.tabId);
|
executeEvent('devModeNavigateBack', selectedTab?.tabId);
|
||||||
}}
|
}}
|
||||||
disabled={isDisableBackButton}
|
disabled={isDisableBackButton}
|
||||||
sx={{
|
sx={{
|
||||||
opacity: !isDisableBackButton ? 1 : 0.1,
|
opacity: !isDisableBackButton ? 1 : 0.1,
|
||||||
cursor: !isDisableBackButton ? 'pointer': 'default'
|
cursor: !isDisableBackButton ? 'pointer' : 'default',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img src={NavBack} />
|
<NavBack />
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
ref={tabsRef}
|
ref={tabsRef}
|
||||||
@ -134,11 +113,11 @@ export const AppsDevModeNavBar = () => {
|
|||||||
variant="scrollable" // Make tabs scrollable
|
variant="scrollable" // Make tabs scrollable
|
||||||
scrollButtons={true}
|
scrollButtons={true}
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiTabs-indicator": {
|
'& .MuiTabs-indicator': {
|
||||||
backgroundColor: "white",
|
backgroundColor: 'white',
|
||||||
},
|
},
|
||||||
maxHeight: `320px`, // Ensure the tabs container fits within the available space
|
maxHeight: `320px`, // Ensure the tabs container fits within the available space
|
||||||
overflow: "hidden", // Prevents overflow on small screens
|
overflow: 'hidden', // Prevents overflow on small screens
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tabs?.map((tab) => (
|
{tabs?.map((tab) => (
|
||||||
@ -153,65 +132,61 @@ export const AppsDevModeNavBar = () => {
|
|||||||
/>
|
/>
|
||||||
} // Pass custom component
|
} // Pass custom component
|
||||||
sx={{
|
sx={{
|
||||||
"&.Mui-selected": {
|
'&.Mui-selected': {
|
||||||
color: "white",
|
color: 'white',
|
||||||
},
|
},
|
||||||
padding: "0px",
|
padding: '0px',
|
||||||
margin: "0px",
|
margin: '0px',
|
||||||
minWidth: "0px",
|
minWidth: '0px',
|
||||||
width: "50px",
|
width: '50px',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</AppsNavBarLeft>
|
</AppsNavBarLeft>
|
||||||
|
|
||||||
{selectedTab && (
|
{selectedTab && (
|
||||||
<AppsNavBarRight
|
<AppsNavBarRight
|
||||||
sx={{
|
sx={{
|
||||||
gap: "10px",
|
gap: '10px',
|
||||||
flexDirection: "column",
|
flexDirection: 'column',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedTab(null);
|
setSelectedTab(null);
|
||||||
executeEvent("devModeNewTabWindow", {});
|
executeEvent('devModeNewTabWindow', {});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<NavAdd
|
||||||
style={{
|
style={{
|
||||||
height: "40px",
|
height: '40px',
|
||||||
width: "40px",
|
width: '40px',
|
||||||
}}
|
}}
|
||||||
src={NavAdd}
|
|
||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (selectedTab?.refreshFunc) {
|
if (selectedTab?.refreshFunc) {
|
||||||
selectedTab.refreshFunc(selectedTab?.tabId)
|
selectedTab.refreshFunc(selectedTab?.tabId);
|
||||||
} else {
|
} else {
|
||||||
executeEvent("refreshApp", {
|
executeEvent('refreshApp', {
|
||||||
tabId: selectedTab?.tabId,
|
tabId: selectedTab?.tabId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RefreshIcon
|
<RefreshIcon
|
||||||
|
|
||||||
sx={{
|
sx={{
|
||||||
color: "rgba(250, 250, 250, 0.5)",
|
color: 'rgba(250, 250, 250, 0.5)',
|
||||||
width: '40px',
|
width: '40px',
|
||||||
height: 'auto'
|
height: 'auto',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</AppsNavBarRight>
|
</AppsNavBarRight>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
</AppsNavBarParent>
|
</AppsNavBarParent>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import React, {
|
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import {
|
import {
|
||||||
AppCircle,
|
AppCircle,
|
||||||
AppCircleContainer,
|
AppCircleContainer,
|
||||||
@ -13,7 +6,6 @@ import {
|
|||||||
AppLibrarySubTitle,
|
AppLibrarySubTitle,
|
||||||
AppsContainer,
|
AppsContainer,
|
||||||
AppsLibraryContainer,
|
AppsLibraryContainer,
|
||||||
AppsParent,
|
|
||||||
AppsSearchContainer,
|
AppsSearchContainer,
|
||||||
AppsSearchLeft,
|
AppsSearchLeft,
|
||||||
AppsSearchRight,
|
AppsSearchRight,
|
||||||
@ -24,16 +16,22 @@ import {
|
|||||||
PublishQAppCTARight,
|
PublishQAppCTARight,
|
||||||
PublishQAppDotsBG,
|
PublishQAppDotsBG,
|
||||||
} from './Apps-styles';
|
} from './Apps-styles';
|
||||||
import { Avatar, Box, ButtonBase, InputBase, styled } from '@mui/material';
|
import {
|
||||||
import { Add } from '@mui/icons-material';
|
Avatar,
|
||||||
|
Box,
|
||||||
|
ButtonBase,
|
||||||
|
InputBase,
|
||||||
|
styled,
|
||||||
|
useTheme,
|
||||||
|
} from '@mui/material';
|
||||||
import { MyContext, getBaseApiReact } from '../../App';
|
import { MyContext, getBaseApiReact } from '../../App';
|
||||||
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
||||||
import IconSearch from '../../assets/svgs/Search.svg';
|
import IconSearch from '../../assets/svgs/Search.svg';
|
||||||
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
||||||
import qappDevelopText from '../../assets/svgs/qappDevelopText.svg';
|
import qappDevelopText from '../../assets/svgs/qappDevelopText.svg';
|
||||||
import qappDots from '../../assets/svgs/qappDots.svg';
|
import qappDots from '../../assets/svgs/qappDots.svg';
|
||||||
|
// import { Return } from './assets/svgs/Return.tsx';
|
||||||
import ReturnSVG from '../../assets/svgs/Return.svg';
|
import ReturnSVG from '../../assets/svgs/Return.svg';
|
||||||
|
|
||||||
import { Spacer } from '../../common/Spacer';
|
import { Spacer } from '../../common/Spacer';
|
||||||
import { AppInfoSnippet } from './AppInfoSnippet';
|
import { AppInfoSnippet } from './AppInfoSnippet';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
@ -43,6 +41,7 @@ import {
|
|||||||
MailIconImg,
|
MailIconImg,
|
||||||
ShowMessageReturnButton,
|
ShowMessageReturnButton,
|
||||||
} from '../Group/Forum/Mail-styles';
|
} from '../Group/Forum/Mail-styles';
|
||||||
|
|
||||||
const officialAppList = [
|
const officialAppList = [
|
||||||
'q-tube',
|
'q-tube',
|
||||||
'q-blog',
|
'q-blog',
|
||||||
@ -59,8 +58,6 @@ const officialAppList = [
|
|||||||
'q-nodecontrol',
|
'q-nodecontrol',
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: apply dark/light style
|
|
||||||
|
|
||||||
const ScrollerStyled = styled('div')({
|
const ScrollerStyled = styled('div')({
|
||||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||||
'::-webkit-scrollbar': {
|
'::-webkit-scrollbar': {
|
||||||
@ -76,10 +73,10 @@ const ScrollerStyled = styled('div')({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const StyledVirtuosoContainer = styled('div')({
|
const StyledVirtuosoContainer = styled('div')({
|
||||||
position: 'relative',
|
|
||||||
width: '100%',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
position: 'relative',
|
||||||
|
width: '100%',
|
||||||
|
|
||||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||||
'::-webkit-scrollbar': {
|
'::-webkit-scrollbar': {
|
||||||
@ -148,6 +145,8 @@ export const AppsLibrary = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppsLibraryContainer
|
<AppsLibraryContainer
|
||||||
sx={{
|
sx={{
|
||||||
@ -165,6 +164,7 @@ export const AppsLibrary = ({
|
|||||||
<AppsSearchContainer>
|
<AppsSearchContainer>
|
||||||
<AppsSearchLeft>
|
<AppsSearchLeft>
|
||||||
<img src={IconSearch} />
|
<img src={IconSearch} />
|
||||||
|
|
||||||
<InputBase
|
<InputBase
|
||||||
value={searchValue}
|
value={searchValue}
|
||||||
onChange={(e) => setSearchValue(e.target.value)}
|
onChange={(e) => setSearchValue(e.target.value)}
|
||||||
@ -191,7 +191,9 @@ export const AppsLibrary = ({
|
|||||||
</AppsSearchContainer>
|
</AppsSearchContainer>
|
||||||
</Box>
|
</Box>
|
||||||
</AppsWidthLimiter>
|
</AppsWidthLimiter>
|
||||||
|
|
||||||
<Spacer height="25px" />
|
<Spacer height="25px" />
|
||||||
|
|
||||||
<ShowMessageReturnButton
|
<ShowMessageReturnButton
|
||||||
sx={{
|
sx={{
|
||||||
padding: '2px',
|
padding: '2px',
|
||||||
@ -200,10 +202,12 @@ export const AppsLibrary = ({
|
|||||||
executeEvent('navigateBack', {});
|
executeEvent('navigateBack', {});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MailIconImg src={ReturnSVG} />
|
<MailIconImg src={ReturnSVG} /> // TODO return icon
|
||||||
<ComposeP>Return to Apps Dashboard</ComposeP>
|
<ComposeP>Return to Apps Dashboard</ComposeP>
|
||||||
</ShowMessageReturnButton>
|
</ShowMessageReturnButton>
|
||||||
|
|
||||||
<Spacer height="25px" />
|
<Spacer height="25px" />
|
||||||
|
|
||||||
{searchedList?.length > 0 ? (
|
{searchedList?.length > 0 ? (
|
||||||
<AppsWidthLimiter>
|
<AppsWidthLimiter>
|
||||||
<StyledVirtuosoContainer
|
<StyledVirtuosoContainer
|
||||||
@ -227,7 +231,9 @@ export const AppsLibrary = ({
|
|||||||
<>
|
<>
|
||||||
<AppsWidthLimiter>
|
<AppsWidthLimiter>
|
||||||
<AppLibrarySubTitle>Official Apps</AppLibrarySubTitle>
|
<AppLibrarySubTitle>Official Apps</AppLibrarySubTitle>
|
||||||
|
|
||||||
<Spacer height="18px" />
|
<Spacer height="18px" />
|
||||||
|
|
||||||
<AppsContainer>
|
<AppsContainer>
|
||||||
{officialApps?.map((qapp) => {
|
{officialApps?.map((qapp) => {
|
||||||
return (
|
return (
|
||||||
@ -271,6 +277,7 @@ export const AppsLibrary = ({
|
|||||||
/>
|
/>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</AppCircle>
|
</AppCircle>
|
||||||
|
|
||||||
<AppCircleLabel>
|
<AppCircleLabel>
|
||||||
{qapp?.metadata?.title || qapp?.name}
|
{qapp?.metadata?.title || qapp?.name}
|
||||||
</AppCircleLabel>
|
</AppCircleLabel>
|
||||||
@ -279,20 +286,27 @@ export const AppsLibrary = ({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</AppsContainer>
|
</AppsContainer>
|
||||||
|
|
||||||
<Spacer height="30px" />
|
<Spacer height="30px" />
|
||||||
|
|
||||||
<AppLibrarySubTitle>
|
<AppLibrarySubTitle>
|
||||||
{hasPublishApp ? 'Update Apps!' : 'Create Apps!'}
|
{hasPublishApp ? 'Update Apps!' : 'Create Apps!'}
|
||||||
</AppLibrarySubTitle>
|
</AppLibrarySubTitle>
|
||||||
|
|
||||||
<Spacer height="18px" />
|
<Spacer height="18px" />
|
||||||
</AppsWidthLimiter>
|
</AppsWidthLimiter>
|
||||||
|
|
||||||
<PublishQAppCTAParent>
|
<PublishQAppCTAParent>
|
||||||
<PublishQAppCTALeft>
|
<PublishQAppCTALeft>
|
||||||
<PublishQAppDotsBG>
|
<PublishQAppDotsBG>
|
||||||
<img src={qappDots} />
|
<img src={qappDots} />
|
||||||
</PublishQAppDotsBG>
|
</PublishQAppDotsBG>
|
||||||
|
|
||||||
<Spacer width="29px" />
|
<Spacer width="29px" />
|
||||||
|
|
||||||
<img src={qappDevelopText} />
|
<img src={qappDevelopText} />
|
||||||
</PublishQAppCTALeft>
|
</PublishQAppCTALeft>
|
||||||
|
|
||||||
<PublishQAppCTARight
|
<PublishQAppCTARight
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setMode('publish');
|
setMode('publish');
|
||||||
@ -301,13 +315,18 @@ export const AppsLibrary = ({
|
|||||||
<PublishQAppCTAButton>
|
<PublishQAppCTAButton>
|
||||||
{hasPublishApp ? 'Update' : 'Publish'}
|
{hasPublishApp ? 'Update' : 'Publish'}
|
||||||
</PublishQAppCTAButton>
|
</PublishQAppCTAButton>
|
||||||
|
|
||||||
<Spacer width="20px" />
|
<Spacer width="20px" />
|
||||||
</PublishQAppCTARight>
|
</PublishQAppCTARight>
|
||||||
</PublishQAppCTAParent>
|
</PublishQAppCTAParent>
|
||||||
|
|
||||||
<AppsWidthLimiter>
|
<AppsWidthLimiter>
|
||||||
<Spacer height="18px" />
|
<Spacer height="18px" />
|
||||||
|
|
||||||
<AppLibrarySubTitle>Categories</AppLibrarySubTitle>
|
<AppLibrarySubTitle>Categories</AppLibrarySubTitle>
|
||||||
|
|
||||||
<Spacer height="18px" />
|
<Spacer height="18px" />
|
||||||
|
|
||||||
<AppsWidthLimiter
|
<AppsWidthLimiter
|
||||||
sx={{
|
sx={{
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
@ -338,18 +357,17 @@ export const AppsLibrary = ({
|
|||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
background: theme.palette.background.default,
|
||||||
height: '110px',
|
|
||||||
width: '110px',
|
|
||||||
background:
|
|
||||||
'linear-gradient(163.47deg, #4BBCFE 27.55%, #1386C9 86.56%)',
|
|
||||||
color: '#1D1D1E',
|
|
||||||
fontWeight: 700,
|
|
||||||
fontSize: '16px',
|
|
||||||
flexShrink: 0,
|
|
||||||
borderRadius: '11px',
|
borderRadius: '11px',
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
display: 'flex',
|
||||||
|
flexShrink: 0,
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 700,
|
||||||
|
height: '110px',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: '110px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{category?.name}
|
{category?.name}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, 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.tsx';
|
||||||
import NavAdd from "../../assets/svgs/NavAdd.svg";
|
import { NavAdd } from '../../assets/svgs/NavAdd.tsx';
|
||||||
import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg";
|
import { NavMoreMenu } from '../../assets/svgs/NavMoreMenu.tsx';
|
||||||
import {
|
import {
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
@ -15,27 +15,33 @@ import {
|
|||||||
MenuItem,
|
MenuItem,
|
||||||
Tab,
|
Tab,
|
||||||
Tabs,
|
Tabs,
|
||||||
} from "@mui/material";
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
executeEvent,
|
executeEvent,
|
||||||
subscribeToEvent,
|
subscribeToEvent,
|
||||||
unsubscribeFromEvent,
|
unsubscribeFromEvent,
|
||||||
} from "../../utils/events";
|
} from '../../utils/events';
|
||||||
import TabComponent from "./TabComponent";
|
import TabComponent from './TabComponent';
|
||||||
import PushPinIcon from "@mui/icons-material/PushPin";
|
import PushPinIcon from '@mui/icons-material/PushPin';
|
||||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import {
|
import {
|
||||||
navigationControllerAtom,
|
navigationControllerAtom,
|
||||||
settingsLocalLastUpdatedAtom,
|
settingsLocalLastUpdatedAtom,
|
||||||
sortablePinnedAppsAtom,
|
sortablePinnedAppsAtom,
|
||||||
} from "../../atoms/global";
|
} from '../../atoms/global';
|
||||||
|
|
||||||
export function saveToLocalStorage(key, subKey, newValue, otherRootData = {}, deleteWholeKey) {
|
export function saveToLocalStorage(
|
||||||
|
key,
|
||||||
|
subKey,
|
||||||
|
newValue,
|
||||||
|
otherRootData = {},
|
||||||
|
deleteWholeKey
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
if (deleteWholeKey) {
|
if (deleteWholeKey) {
|
||||||
localStorage.setItem(key, null);
|
localStorage.setItem(key, null);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
// Fetch existing data
|
// Fetch existing data
|
||||||
const existingData = localStorage.getItem(key);
|
const existingData = localStorage.getItem(key);
|
||||||
@ -64,7 +70,7 @@ export function saveToLocalStorage(key, subKey, newValue, otherRootData = {}, de
|
|||||||
const serializedValue = JSON.stringify(combinedData);
|
const serializedValue = JSON.stringify(combinedData);
|
||||||
localStorage.setItem(key, serializedValue);
|
localStorage.setItem(key, serializedValue);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error saving to localStorage:", error);
|
console.error('Error saving to localStorage:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,13 +84,17 @@ export const AppsNavBar = () => {
|
|||||||
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
|
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
|
||||||
sortablePinnedAppsAtom
|
sortablePinnedAppsAtom
|
||||||
);
|
);
|
||||||
const [navigationController, setNavigationController] = useRecoilState(navigationControllerAtom)
|
const [navigationController, setNavigationController] = useRecoilState(
|
||||||
|
navigationControllerAtom
|
||||||
|
);
|
||||||
|
|
||||||
const isDisableBackButton = useMemo(() => {
|
const isDisableBackButton = useMemo(() => {
|
||||||
if(selectedTab && navigationController[selectedTab?.tabId]?.hasBack) return false
|
if (selectedTab && navigationController[selectedTab?.tabId]?.hasBack)
|
||||||
if(selectedTab && !navigationController[selectedTab?.tabId]?.hasBack) return true
|
return false;
|
||||||
return false
|
if (selectedTab && !navigationController[selectedTab?.tabId]?.hasBack)
|
||||||
}, [navigationController, selectedTab])
|
return true;
|
||||||
|
return false;
|
||||||
|
}, [navigationController, selectedTab]);
|
||||||
|
|
||||||
const setSettingsLocalLastUpdated = useSetRecoilState(
|
const setSettingsLocalLastUpdated = useSetRecoilState(
|
||||||
settingsLocalLastUpdatedAtom
|
settingsLocalLastUpdatedAtom
|
||||||
@ -101,13 +111,13 @@ export const AppsNavBar = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
||||||
if (tabsRef.current) {
|
if (tabsRef.current) {
|
||||||
const tabElements = tabsRef.current.querySelectorAll(".MuiTab-root");
|
const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root');
|
||||||
if (tabElements.length > 0) {
|
if (tabElements.length > 0) {
|
||||||
const lastTab = tabElements[tabElements.length - 1];
|
const lastTab = tabElements[tabElements.length - 1];
|
||||||
lastTab.scrollIntoView({
|
lastTab.scrollIntoView({
|
||||||
behavior: "smooth",
|
behavior: 'smooth',
|
||||||
block: "nearest",
|
block: 'nearest',
|
||||||
inline: "end",
|
inline: 'end',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,10 +132,10 @@ export const AppsNavBar = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subscribeToEvent("setTabsToNav", setTabsToNav);
|
subscribeToEvent('setTabsToNav', setTabsToNav);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeFromEvent("setTabsToNav", setTabsToNav);
|
unsubscribeFromEvent('setTabsToNav', setTabsToNav);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -138,27 +148,28 @@ export const AppsNavBar = () => {
|
|||||||
<AppsNavBarLeft>
|
<AppsNavBarLeft>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
executeEvent("navigateBack", selectedTab?.tabId);
|
executeEvent('navigateBack', selectedTab?.tabId);
|
||||||
}}
|
}}
|
||||||
disabled={isDisableBackButton}
|
disabled={isDisableBackButton}
|
||||||
sx={{
|
sx={{
|
||||||
opacity: !isDisableBackButton ? 1 : 0.1,
|
opacity: !isDisableBackButton ? 1 : 0.3,
|
||||||
cursor: !isDisableBackButton ? 'pointer': 'default'
|
cursor: !isDisableBackButton ? 'pointer' : 'default',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img src={NavBack} />
|
<NavBack />
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
ref={tabsRef}
|
ref={tabsRef}
|
||||||
aria-label="basic tabs example"
|
aria-label="basic tabs example"
|
||||||
variant="scrollable" // Make tabs scrollable
|
variant="scrollable" // Make tabs scrollable
|
||||||
scrollButtons={false}
|
scrollButtons={false}
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiTabs-indicator": {
|
'& .MuiTabs-indicator': {
|
||||||
backgroundColor: "white",
|
backgroundColor: 'white',
|
||||||
},
|
},
|
||||||
maxWidth: `calc(100vw - 150px)`, // Ensure the tabs container fits within the available space
|
maxWidth: `calc(100vw - 150px)`, // Ensure the tabs container fits within the available space
|
||||||
overflow: "hidden", // Prevents overflow on small screens
|
overflow: 'hidden', // Prevents overflow on small screens
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tabs?.map((tab) => (
|
{tabs?.map((tab) => (
|
||||||
@ -173,50 +184,50 @@ export const AppsNavBar = () => {
|
|||||||
/>
|
/>
|
||||||
} // Pass custom component
|
} // Pass custom component
|
||||||
sx={{
|
sx={{
|
||||||
"&.Mui-selected": {
|
'&.Mui-selected': {
|
||||||
color: "white",
|
color: 'white',
|
||||||
},
|
},
|
||||||
padding: "0px",
|
padding: '0px',
|
||||||
margin: "0px",
|
margin: '0px',
|
||||||
minWidth: "0px",
|
minWidth: '0px',
|
||||||
width: "50px",
|
width: '50px',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</AppsNavBarLeft>
|
</AppsNavBarLeft>
|
||||||
|
|
||||||
{selectedTab && (
|
{selectedTab && (
|
||||||
<AppsNavBarRight
|
<AppsNavBarRight
|
||||||
sx={{
|
sx={{
|
||||||
gap: "10px",
|
gap: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedTab(null);
|
setSelectedTab(null);
|
||||||
executeEvent("newTabWindow", {});
|
executeEvent('newTabWindow', {});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<NavAdd
|
||||||
style={{
|
style={{
|
||||||
height: "40px",
|
height: '40px',
|
||||||
width: "40px",
|
width: '40px',
|
||||||
}}
|
}}
|
||||||
src={NavAdd}
|
|
||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (!selectedTab) return;
|
if (!selectedTab) return;
|
||||||
handleClick(e);
|
handleClick(e);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<NavMoreMenu
|
||||||
style={{
|
style={{
|
||||||
height: "34px",
|
height: '34px',
|
||||||
width: "34px",
|
width: '34px',
|
||||||
}}
|
}}
|
||||||
src={NavMoreMenu}
|
|
||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</AppsNavBarRight>
|
</AppsNavBarRight>
|
||||||
@ -228,28 +239,28 @@ export const AppsNavBar = () => {
|
|||||||
open={open}
|
open={open}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
MenuListProps={{
|
MenuListProps={{
|
||||||
"aria-labelledby": "basic-button",
|
'aria-labelledby': 'basic-button',
|
||||||
}}
|
}}
|
||||||
anchorOrigin={{
|
anchorOrigin={{
|
||||||
vertical: "bottom",
|
vertical: 'bottom',
|
||||||
horizontal: "center",
|
horizontal: 'center',
|
||||||
}}
|
}}
|
||||||
transformOrigin={{
|
transformOrigin={{
|
||||||
vertical: "top",
|
vertical: 'top',
|
||||||
horizontal: "center",
|
horizontal: 'center',
|
||||||
}}
|
}}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
paper: {
|
paper: {
|
||||||
sx: {
|
sx: {
|
||||||
backgroundColor: "var(--bg-primary)",
|
backgroundColor: 'var(--bg-primary)',
|
||||||
color: "#fff",
|
color: '#fff',
|
||||||
width: "148px",
|
width: '148px',
|
||||||
borderRadius: "5px",
|
borderRadius: '5px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
marginTop: "10px",
|
marginTop: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -280,8 +291,8 @@ export const AppsNavBar = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveToLocalStorage(
|
saveToLocalStorage(
|
||||||
"ext_saved_settings",
|
'ext_saved_settings',
|
||||||
"sortablePinnedApps",
|
'sortablePinnedApps',
|
||||||
updatedApps
|
updatedApps
|
||||||
);
|
);
|
||||||
return updatedApps;
|
return updatedApps;
|
||||||
@ -293,31 +304,33 @@ export const AppsNavBar = () => {
|
|||||||
>
|
>
|
||||||
<ListItemIcon
|
<ListItemIcon
|
||||||
sx={{
|
sx={{
|
||||||
minWidth: "24px !important",
|
minWidth: '24px !important',
|
||||||
marginRight: "5px",
|
marginRight: '5px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PushPinIcon
|
<PushPinIcon
|
||||||
height={20}
|
height={20}
|
||||||
sx={{
|
sx={{
|
||||||
color: isSelectedAppPinned ? "red" : "rgba(250, 250, 250, 0.5)",
|
color: isSelectedAppPinned ? 'red' : 'rgba(250, 250, 250, 0.5)',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiTypography-root": {
|
'& .MuiTypography-root': {
|
||||||
fontSize: "12px",
|
fontSize: '12px',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
color: isSelectedAppPinned ? "red" : "rgba(250, 250, 250, 0.5)",
|
color: isSelectedAppPinned ? 'red' : 'rgba(250, 250, 250, 0.5)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
primary={`${isSelectedAppPinned ? "Unpin app" : "Pin app"}`}
|
primary={`${isSelectedAppPinned ? 'Unpin app' : 'Pin app'}`}
|
||||||
/>
|
/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
executeEvent("refreshApp", {
|
executeEvent('refreshApp', {
|
||||||
tabId: selectedTab?.tabId,
|
tabId: selectedTab?.tabId,
|
||||||
});
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -325,23 +338,24 @@ export const AppsNavBar = () => {
|
|||||||
>
|
>
|
||||||
<ListItemIcon
|
<ListItemIcon
|
||||||
sx={{
|
sx={{
|
||||||
minWidth: "24px !important",
|
minWidth: '24px !important',
|
||||||
marginRight: "5px",
|
marginRight: '5px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RefreshIcon
|
<RefreshIcon
|
||||||
height={20}
|
height={20}
|
||||||
sx={{
|
sx={{
|
||||||
color: "rgba(250, 250, 250, 0.5)",
|
color: 'rgba(250, 250, 250, 0.5)',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiTypography-root": {
|
'& .MuiTypography-root': {
|
||||||
fontSize: "12px",
|
fontSize: '12px',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
color: "rgba(250, 250, 250, 0.5)",
|
color: 'rgba(250, 250, 250, 0.5)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
primary="Refresh"
|
primary="Refresh"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user