added devmode

This commit is contained in:
PhilReact 2024-11-02 07:53:42 +02:00
parent a499b25050
commit ebfd6db4dc
13 changed files with 927 additions and 39 deletions

View File

@ -103,6 +103,7 @@ import { useQortalGetSaveSettings } from "./useQortalGetSaveSettings";
import { useRecoilState, useResetRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useResetRecoilState, useSetRecoilState } from "recoil";
import { import {
canSaveSettingToQdnAtom, canSaveSettingToQdnAtom,
enabledDevModeAtom,
fullScreenAtom, fullScreenAtom,
hasSettingsChangedAtom, hasSettingsChangedAtom,
oldPinnedAppsAtom, oldPinnedAppsAtom,
@ -370,9 +371,17 @@ function App() {
useRetrieveDataLocalStorage(); useRetrieveDataLocalStorage();
useQortalGetSaveSettings(userInfo?.name); useQortalGetSaveSettings(userInfo?.name);
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom); const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
const { toggleFullScreen } = useAppFullScreen(setFullScreen); const { toggleFullScreen } = useAppFullScreen(setFullScreen);
useEffect(()=> {
const isDevModeFromStorage = localStorage.getItem('isEnabledDevMode');
if(isDevModeFromStorage){
setIsEnabledDevMode(JSON.parse(isDevModeFromStorage))
}
}, [])
useEffect(() => { useEffect(() => {
// Attach a global event listener for double-click // Attach a global event listener for double-click
const handleDoubleClick = () => { const handleDoubleClick = () => {
@ -1519,7 +1528,7 @@ function App() {
desktopViewMode={desktopViewMode} desktopViewMode={desktopViewMode}
setDesktopViewMode={setDesktopViewMode} setDesktopViewMode={setDesktopViewMode}
/> />
{!isMobile && desktopViewMode !== "apps" && renderProfile()} {!isMobile && desktopViewMode !== "apps" && desktopViewMode !== "dev" && renderProfile()}
</Box> </Box>
<Box <Box

View File

@ -61,4 +61,9 @@ export const hasSettingsChangedAtom = atom({
export const navigationControllerAtom = atom({ export const navigationControllerAtom = atom({
key: 'navigationControllerAtom', key: 'navigationControllerAtom',
default: {}, default: {},
});
export const enabledDevModeAtom = atom({
key: 'enabledDevModeAtom',
default: false,
}); });

View File

@ -11,25 +11,35 @@ import { useQortalMessageListener } from "./useQortalMessageListener";
export const AppViewer = React.forwardRef(({ app , hide}, iframeRef) => { export const AppViewer = React.forwardRef(({ app , hide, isDevMode}, iframeRef) => {
const { rootHeight } = useContext(MyContext); const { rootHeight } = useContext(MyContext);
// const iframeRef = useRef(null); // const iframeRef = useRef(null);
const { document, window: frameWindow } = useFrame(); const { document, window: frameWindow } = useFrame();
const {path, history, changeCurrentIndex} = useQortalMessageListener(frameWindow, iframeRef, app?.tabId) const {path, history, changeCurrentIndex} = useQortalMessageListener(frameWindow, iframeRef, app?.tabId, isDevMode)
const [url, setUrl] = useState('') const [url, setUrl] = useState('')
useEffect(()=> { useEffect(()=> {
if(isDevMode){
setUrl(app?.url)
return
}
setUrl(`${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? `/${app?.path}` : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}`) setUrl(`${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? `/${app?.path}` : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}`)
}, [app?.service, app?.name, app?.identifier, app?.path]) }, [app?.service, app?.name, app?.identifier, app?.path])
const defaultUrl = useMemo(()=> { const defaultUrl = useMemo(()=> {
return url return url
}, [url]) }, [url, isDevMode])
const refreshAppFunc = (e) => { const refreshAppFunc = (e) => {
const {tabId} = e.detail const {tabId} = e.detail
if(tabId === app?.tabId){ if(tabId === app?.tabId){
if(isDevMode){
setUrl(app?.url + `?time=${Date.now()}`)
return
}
const constructUrl = `${getBaseApiReact()}/render/${app?.service}/${app?.name}${path != null ? path : ''}?theme=dark&identifier=${app?.identifier != null ? app?.identifier : ''}&time=${new Date().getMilliseconds()}` const constructUrl = `${getBaseApiReact()}/render/${app?.service}/${app?.name}${path != null ? path : ''}?theme=dark&identifier=${app?.identifier != null ? app?.identifier : ''}&time=${new Date().getMilliseconds()}`
setUrl(constructUrl) setUrl(constructUrl)
} }
@ -41,7 +51,7 @@ export const AppViewer = React.forwardRef(({ app , hide}, iframeRef) => {
return () => { return () => {
unsubscribeFromEvent("refreshApp", refreshAppFunc); unsubscribeFromEvent("refreshApp", refreshAppFunc);
}; };
}, [app, path]); }, [app, path, isDevMode]);
// Function to navigate back in iframe // Function to navigate back in iframe
const navigateBackInIframe = async () => { const navigateBackInIframe = async () => {

View File

@ -3,7 +3,7 @@ import { AppViewer } from './AppViewer';
import Frame from 'react-frame-component'; import Frame from 'react-frame-component';
import { MyContext, isMobile } from '../../App'; import { MyContext, isMobile } from '../../App';
const AppViewerContainer = React.forwardRef(({ app, isSelected, hide }, ref) => { const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode }, ref) => {
const { rootHeight } = useContext(MyContext); const { rootHeight } = useContext(MyContext);
@ -42,7 +42,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide }, ref) =>
overflow: 'hidden', overflow: 'hidden',
}} }}
> >
<AppViewer app={app} ref={ref} hide={!isSelected || hide} /> <AppViewer app={app} ref={ref} hide={!isSelected || hide} isDevMode={isDevMode} />
</Frame> </Frame>
); );
}); });

View File

@ -0,0 +1,310 @@
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
import { AppsDevModeHome } from "./AppsDevModeHome";
import { Spacer } from "../../common/Spacer";
import { MyContext, getBaseApiReact } from "../../App";
import { AppInfo } from "./AppInfo";
import {
executeEvent,
subscribeToEvent,
unsubscribeFromEvent,
} from "../../utils/events";
import { AppsParent } from "./Apps-styles";
import AppViewerContainer from "./AppViewerContainer";
import ShortUniqueId from "short-unique-id";
import { AppPublish } from "./AppPublish";
import { AppsLibraryDesktop } from "./AppsLibraryDesktop";
import { AppsCategoryDesktop } from "./AppsCategoryDesktop";
import { AppsNavBarDesktop } from "./AppsNavBarDesktop";
import { Box, ButtonBase } from "@mui/material";
import { HomeIcon } from "../../assets/Icons/HomeIcon";
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import { Save } from "../Save/Save";
import { HubsIcon } from "../../assets/Icons/HubsIcon";
import { AppsDevModeNavBar } from "./AppsDevModeNavBar";
const uid = new ShortUniqueId({ length: 8 });
export const AppsDevMode = ({ mode, setMode, show , myName, goToHome, setDesktopSideView, hasUnreadDirects, isDirects, isGroups, hasUnreadGroups, toggleSideViewGroups, toggleSideViewDirects}) => {
const [availableQapps, setAvailableQapps] = useState([]);
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
const [selectedCategory, setSelectedCategory] = useState(null)
const [tabs, setTabs] = useState([]);
const [selectedTab, setSelectedTab] = useState(null);
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const [categories, setCategories] = useState([])
const iframeRefs = useRef({});
useEffect(() => {
setTimeout(() => {
executeEvent("appsDevModeSetTabsToNav", {
data: {
tabs: tabs,
selectedTab: selectedTab,
isNewTabWindow: isNewTabWindow,
},
});
}, 100);
}, [show, tabs, selectedTab, isNewTabWindow]);
const navigateBackFunc = (e) => {
if (['category', 'appInfo-from-category', 'appInfo', 'library', 'publish'].includes(mode)) {
// Handle the various modes as needed
if (mode === 'category') {
setMode('library');
setSelectedCategory(null);
} else if (mode === 'appInfo-from-category') {
setMode('category');
} else if (mode === 'appInfo') {
setMode('library');
} else if (mode === 'library') {
if (isNewTabWindow) {
setMode('viewer');
} else {
setMode('home');
}
} else if (mode === 'publish') {
setMode('library');
}
} else if(selectedTab?.tabId) {
executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {})
}
};
useEffect(() => {
subscribeToEvent("devModeNavigateBack", navigateBackFunc);
return () => {
unsubscribeFromEvent("devModeNavigateBack", navigateBackFunc);
};
}, [mode, selectedTab]);
const addTabFunc = (e) => {
const data = e.detail?.data;
const newTab = {
...data,
tabId: uid.rnd(),
};
setTabs((prev) => [...prev, newTab]);
setSelectedTab(newTab);
setMode("viewer");
setIsNewTabWindow(false);
};
useEffect(() => {
subscribeToEvent("appsDevModeAddTab", addTabFunc);
return () => {
unsubscribeFromEvent("appsDevModeAddTab", addTabFunc);
};
}, [tabs]);
const setSelectedTabFunc = (e) => {
const data = e.detail?.data;
setSelectedTab(data);
setTimeout(() => {
executeEvent("appsDevModeSetTabsToNav", {
data: {
tabs: tabs,
selectedTab: data,
isNewTabWindow: isNewTabWindow,
},
});
}, 100);
setIsNewTabWindow(false);
};
useEffect(() => {
subscribeToEvent("setSelectedTab", setSelectedTabFunc);
return () => {
unsubscribeFromEvent("setSelectedTab", setSelectedTabFunc);
};
}, [tabs, isNewTabWindow]);
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);
setSelectedTab(null)
};
useEffect(() => {
subscribeToEvent("devModeNewTabWindow", setNewTabWindowFunc);
return () => {
unsubscribeFromEvent("devModeNewTabWindow", setNewTabWindowFunc);
};
}, [tabs]);
return (
<AppsParent
sx={{
display: !show && "none",
flexDirection: 'row'
}}
>
<Box sx={{
width: '60px',
flexDirection: 'column',
height: '100vh',
alignItems: 'center',
display: 'flex',
gap: '30px'
}}>
<ButtonBase
sx={{
width: '60px',
height: '60px',
paddingTop: '23px'
}}
onClick={() => {
goToHome();
}}
>
<HomeIcon
height={34}
color="rgba(250, 250, 250, 0.5)"
/>
</ButtonBase>
<ButtonBase
onClick={() => {
setDesktopSideView("directs");
toggleSideViewDirects()
}}
>
<MessagingIcon
height={30}
color={
hasUnreadDirects
? "var(--unread)"
: isDirects
? "white"
: "rgba(250, 250, 250, 0.5)"
}
/>
</ButtonBase>
<ButtonBase
onClick={() => {
setDesktopSideView("groups");
toggleSideViewGroups()
}}
>
<HubsIcon
height={30}
color={
hasUnreadGroups
? "var(--unread)"
: isGroups
? "white"
: "rgba(250, 250, 250, 0.5)"
}
/>
</ButtonBase>
<Save isDesktop />
{mode !== 'home' && (
<AppsDevModeNavBar />
)}
</Box>
{mode === "home" && (
<Box sx={{
display: 'flex',
width: '100%',
flexDirection: 'column',
height: '100vh',
overflow: 'auto'
}}>
<Spacer height="30px" />
<AppsDevModeHome availableQapps={availableQapps} setMode={setMode} myApp={null} myWebsite={null} />
</Box>
)}
{tabs.map((tab) => {
if (!iframeRefs.current[tab.tabId]) {
iframeRefs.current[tab.tabId] = React.createRef();
}
return (
<AppViewerContainer
key={tab?.tabId}
hide={isNewTabWindow}
isSelected={tab?.tabId === selectedTab?.tabId}
app={tab}
ref={iframeRefs.current[tab.tabId]}
isDevMode={true}
/>
);
})}
{isNewTabWindow && mode === "viewer" && (
<>
<Box sx={{
display: 'flex',
width: '100%',
flexDirection: 'column',
height: '100vh',
overflow: 'auto'
}}>
<Spacer height="30px" />
<AppsDevModeHome availableQapps={availableQapps} setMode={setMode} myApp={null} myWebsite={null} />
</Box>
</>
)}
</AppsParent>
);
};

View File

@ -0,0 +1,183 @@
import React, { useContext, useMemo, useState } from "react";
import {
AppCircle,
AppCircleContainer,
AppCircleLabel,
AppLibrarySubTitle,
AppsContainer,
AppsParent,
} from "./Apps-styles";
import {
Avatar,
Box,
Button,
ButtonBase,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Input,
} from "@mui/material";
import { Add } from "@mui/icons-material";
import { MyContext, getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events";
import { Spacer } from "../../common/Spacer";
import { AppsDevModeSortablePinnedApps } from "./AppsDevModeSortablePinnedApps";
import { useModal } from "../../common/useModal";
import { isUsingLocal } from "../../background";
import { Label } from "../Group/AddGroup";
export const AppsDevModeHome = ({
setMode,
myApp,
myWebsite,
availableQapps,
}) => {
const [domain, setDomain] = useState("");
const [port, setPort] = useState("");
const { isShow, onCancel, onOk, show, message } = useModal();
const {
openSnackGlobal,
setOpenSnackGlobal,
infoSnackCustom,
setInfoSnackCustom,
} = useContext(MyContext);
const addDevModeApp = async () => {
try {
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: "error",
message:
"Please use your local node for dev mode! Logout and use Local node.",
});
return;
}
await show({
message: "",
publishFee: "",
});
const framework = domain + ":" + port;
const response = await fetch(
`${getBaseApiReact()}/developer/proxy/start`,
{
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: framework,
}
);
const responseData = await response.text();
executeEvent("appsDevModeAddTab", {
data: {
url: "http://127.0.0.1:" + responseData,
},
});
} catch (error) {}
};
return (
<>
<AppsContainer
sx={{
justifyContent: "flex-start",
}}
>
<AppLibrarySubTitle
sx={{
fontSize: "30px",
}}
>
Dev Mode Apps
</AppLibrarySubTitle>
</AppsContainer>
<Spacer height="45px" />
<AppsContainer
sx={{
gap: "75px",
justifyContent: "flex-start",
}}
>
<ButtonBase
onClick={() => {
addDevModeApp();
}}
>
<AppCircleContainer
sx={{
gap: !isMobile ? "10px" : "5px",
}}
>
<AppCircle>
<Add>+</Add>
</AppCircle>
<AppCircleLabel>App</AppCircleLabel>
</AppCircleContainer>
</ButtonBase>
</AppsContainer>
{isShow && (
<Dialog
open={isShow}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
{"Add custom framework"}
</DialogTitle>
<DialogContent>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
}}
>
<Label>Domain</Label>
<Input
placeholder="Domain"
value={domain}
onChange={(e) => setDomain(e.target.value)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "5px",
marginTop: '15px'
}}
>
<Label>Port</Label>
<Input
placeholder="Port"
value={port}
onChange={(e) => setPort(e.target.value)}
/>
</Box>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCancel}>
Close
</Button>
<Button
disabled={!domain || !port}
variant="contained"
onClick={onOk}
autoFocus
>
Add
</Button>
</DialogActions>
</Dialog>
)}
</>
);
};

View File

@ -0,0 +1,272 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import {
AppsNavBarLeft,
AppsNavBarParent,
AppsNavBarRight,
} from "./Apps-styles";
import NavBack from "../../assets/svgs/NavBack.svg";
import NavAdd from "../../assets/svgs/NavAdd.svg";
import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg";
import {
ButtonBase,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Tab,
Tabs,
} from "@mui/material";
import {
executeEvent,
subscribeToEvent,
unsubscribeFromEvent,
} from "../../utils/events";
import TabComponent from "./TabComponent";
import PushPinIcon from "@mui/icons-material/PushPin";
import RefreshIcon from "@mui/icons-material/Refresh";
import { useRecoilState, useSetRecoilState } from "recoil";
import {
navigationControllerAtom,
settingsLocalLastUpdatedAtom,
sortablePinnedAppsAtom,
} from "../../atoms/global";
import { AppsDevModeTabComponent } from "./AppsDevModeTabComponent";
export const AppsDevModeNavBar = () => {
const [tabs, setTabs] = useState([]);
const [selectedTab, setSelectedTab] = useState(null);
const [navigationController, setNavigationController] = useRecoilState(navigationControllerAtom)
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const tabsRef = useRef(null);
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(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");
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 isDisableBackButton = useMemo(()=> {
if(selectedTab && navigationController[selectedTab?.tabId]?.hasBack) return false
if(selectedTab && !navigationController[selectedTab?.tabId]?.hasBack) return true
return false
}, [navigationController, selectedTab])
const setTabsToNav = (e) => {
const { tabs, selectedTab, isNewTabWindow } = e.detail?.data;
setTabs([...tabs]);
setSelectedTab(!selectedTab ? null : { ...selectedTab });
setIsNewTabWindow(isNewTabWindow);
};
useEffect(() => {
subscribeToEvent("appsDevModeSetTabsToNav", setTabsToNav);
return () => {
unsubscribeFromEvent("appsDevModeSetTabsToNav", setTabsToNav);
};
}, []);
return (
<AppsNavBarParent
sx={{
position: "relative",
flexDirection: "column",
width: "60px",
height: "unset",
maxHeight: "70vh",
borderRadius: "0px 30px 30px 0px",
padding: "10px",
}}
>
<AppsNavBarLeft
sx={{
flexDirection: "column",
}}
>
<ButtonBase
onClick={() => {
executeEvent("devModeNavigateBack", selectedTab?.tabId);
}}
disabled={isDisableBackButton}
sx={{
opacity: !isDisableBackButton ? 1 : 0.1,
cursor: !isDisableBackButton ? 'pointer': 'default'
}}
>
<img src={NavBack} />
</ButtonBase>
<Tabs
orientation="vertical"
ref={tabsRef}
aria-label="basic tabs example"
variant="scrollable" // Make tabs scrollable
scrollButtons={true}
sx={{
"& .MuiTabs-indicator": {
backgroundColor: "white",
},
maxHeight: `320px`, // Ensure the tabs container fits within the available space
overflow: "hidden", // Prevents overflow on small screens
}}
>
{tabs?.map((tab) => (
<Tab
key={tab.tabId}
label={
<AppsDevModeTabComponent
isSelected={
tab?.tabId === selectedTab?.tabId && !isNewTabWindow
}
app={tab}
/>
} // Pass custom component
sx={{
"&.Mui-selected": {
color: "white",
},
padding: "0px",
margin: "0px",
minWidth: "0px",
width: "50px",
}}
/>
))}
</Tabs>
</AppsNavBarLeft>
{selectedTab && (
<AppsNavBarRight
sx={{
gap: "10px",
flexDirection: "column",
}}
>
<ButtonBase
onClick={() => {
setSelectedTab(null);
executeEvent("devModeNewTabWindow", {});
}}
>
<img
style={{
height: "40px",
width: "40px",
}}
src={NavAdd}
/>
</ButtonBase>
<ButtonBase
onClick={(e) => {
if (!selectedTab) return;
handleClick(e);
}}
>
<img
style={{
height: "34px",
width: "34px",
}}
src={NavMoreMenu}
/>
</ButtonBase>
</AppsNavBarRight>
)}
<Menu
id="navbar-more-mobile"
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={() => {
executeEvent("refreshApp", {
tabId: selectedTab?.tabId,
});
handleClose();
}}
>
<ListItemIcon
sx={{
minWidth: "24px !important",
marginRight: "5px",
}}
>
<RefreshIcon
height={20}
sx={{
color: "rgba(250, 250, 250, 0.5)",
}}
/>
</ListItemIcon>
<ListItemText
sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Refresh"
/>
</MenuItem>
</Menu>
</AppsNavBarParent>
);
};

View File

@ -0,0 +1,58 @@
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';
export const AppsDevModeTabComponent = ({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: "28px",
width: "28px",
}}
alt=''
src={``}
>
<img
style={{
width: "28px",
height: "auto",
}}
src={LogoSelected}
alt="center-icon"
/>
</Avatar>
</TabParent>
</ButtonBase>
)
}

View File

@ -12,8 +12,8 @@ import { Add } from "@mui/icons-material";
import { getBaseApiReact, isMobile } from "../../App"; import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg"; import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { SortablePinnedApps } from "./SortablePinnedApps";
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { SortablePinnedApps } from "./SortablePinnedApps";
export const AppsHomeDesktop = ({ export const AppsHomeDesktop = ({
setMode, setMode,

View File

@ -383,7 +383,7 @@ const UIQortalRequests = [
return obj; // Updated object with references to stored files return obj; // Updated object with references to stored files
} }
export const useQortalMessageListener = (frameWindow, iframeRef, tabId) => { export const useQortalMessageListener = (frameWindow, iframeRef, tabId, isDevMode) => {
const [path, setPath] = useState('') const [path, setPath] = useState('')
const [history, setHistory] = useState({ const [history, setHistory] = useState({
customQDNHistoryPaths: [], customQDNHistoryPaths: [],
@ -530,7 +530,7 @@ isDOMContentLoaded: false
setHistory(event?.data?.payload) setHistory(event?.data?.payload)
} }
} else if(event?.data?.action === 'SET_TAB'){ } else if(event?.data?.action === 'SET_TAB' && !isDevMode){
executeEvent("addTab", { executeEvent("addTab", {
data: event?.data?.payload data: event?.data?.payload
}) })
@ -553,7 +553,7 @@ isDOMContentLoaded: false
}; };
}, []); // Empty dependency array to run once when the component mounts }, [isDevMode]); // Empty dependency array to run once when the component mounts

View File

@ -17,6 +17,8 @@ import AppIcon from "../../assets/svgs/AppIcon.svg";
import { HomeIcon } from "../../assets/Icons/HomeIcon"; import { HomeIcon } from "../../assets/Icons/HomeIcon";
import { Save } from "../Save/Save"; import { Save } from "../Save/Save";
import { useRecoilState } from "recoil";
import { enabledDevModeAtom } from "../../atoms/global";
export const IconWrapper = ({ children, label, color, selected }) => { export const IconWrapper = ({ children, label, color, selected }) => {
return ( return (
@ -81,7 +83,8 @@ export const DesktopFooter = ({
setIsOpenSideViewGroups setIsOpenSideViewGroups
}) => { }) => {
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
if(hide) return if(hide) return
return ( return (
<Box <Box
@ -179,6 +182,24 @@ export const DesktopFooter = ({
</ButtonBase> </ButtonBase>
<Save isDesktop /> <Save isDesktop />
{isEnabledDevMode && (
<ButtonBase
onClick={() => {
setDesktopViewMode('dev')
setIsOpenSideViewDirects(false)
setIsOpenSideViewGroups(false)
}}
>
<IconWrapper
color="rgba(250, 250, 250, 0.5)"
label="Dev Mode"
selected={isApps}
>
<img src={AppIcon} />
</IconWrapper>
</ButtonBase>
)}
</Box> </Box>
</Box> </Box>
); );

View File

@ -91,6 +91,7 @@ import { DesktopHeader } from "../Desktop/DesktopHeader";
import { Apps } from "../Apps/Apps"; import { Apps } from "../Apps/Apps";
import { AppsNavBar } from "../Apps/AppsNavBar"; import { AppsNavBar } from "../Apps/AppsNavBar";
import { AppsDesktop } from "../Apps/AppsDesktop"; import { AppsDesktop } from "../Apps/AppsDesktop";
import { AppsDevMode } from "../Apps/AppsDevMode";
// let touchStartY = 0; // let touchStartY = 0;
// let disablePullToRefresh = false; // let disablePullToRefresh = false;
@ -437,6 +438,7 @@ export const Group = ({
const initiatedGetMembers = useRef(false); const initiatedGetMembers = useRef(false);
const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({}); const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({});
const [appsMode, setAppsMode] = useState('home') const [appsMode, setAppsMode] = useState('home')
const [appsModeDev, setAppsModeDev] = useState('home')
const [isOpenSideViewDirects, setIsOpenSideViewDirects] = useState(false) const [isOpenSideViewDirects, setIsOpenSideViewDirects] = useState(false)
const [isOpenSideViewGroups, setIsOpenSideViewGroups] = useState(false) const [isOpenSideViewGroups, setIsOpenSideViewGroups] = useState(false)
const toggleSideViewDirects = ()=> { const toggleSideViewDirects = ()=> {
@ -1553,6 +1555,8 @@ export const Group = ({
} }
}; };
console.log('desktopViewMode', desktopViewMode)
const renderDirects = () => { const renderDirects = () => {
return ( return (
<div <div
@ -2021,8 +2025,8 @@ export const Group = ({
alignItems: "flex-start", alignItems: "flex-start",
}} }}
> >
{!isMobile && ((desktopSideView === 'groups' && desktopViewMode !== 'apps') || isOpenSideViewGroups) && renderGroups()} {!isMobile && ((desktopSideView === 'groups' && desktopViewMode !== 'apps' && desktopViewMode !== 'dev') || isOpenSideViewGroups) && renderGroups()}
{!isMobile && ((desktopSideView === 'directs' && desktopViewMode !== 'apps') || isOpenSideViewDirects) && renderDirects()} {!isMobile && ((desktopSideView === 'directs' && desktopViewMode !== 'apps' && desktopViewMode !== 'dev') || isOpenSideViewDirects) && renderDirects()}
<Box <Box
sx={{ sx={{
@ -2480,13 +2484,13 @@ export const Group = ({
hasUnreadDirects={directChatHasUnread} hasUnreadDirects={directChatHasUnread}
myName={userInfo?.name || null} myName={userInfo?.name || null}
isHome={groupSection === "home" && desktopViewMode === 'home'} isHome={groupSection === "home" && desktopViewMode === 'home'}
isGroups={desktopSideView === 'groups' && desktopViewMode !== 'apps'} isGroups={desktopSideView === 'groups' && desktopViewMode !== 'apps' && desktopViewMode !== 'apps'}
isDirects={desktopSideView === 'directs' && desktopViewMode !== 'apps'} isDirects={desktopSideView === 'directs' && desktopViewMode !== 'apps' && desktopViewMode !== 'apps'}
setDesktopViewMode={setDesktopViewMode} setDesktopViewMode={setDesktopViewMode}
isApps={desktopViewMode === 'apps'} isApps={desktopViewMode === 'apps'}
setDesktopSideView={setDesktopSideView} setDesktopSideView={setDesktopSideView}
desktopViewMode={desktopViewMode} desktopViewMode={desktopViewMode}
hide={desktopViewMode === 'apps'} hide={desktopViewMode === 'apps' || desktopViewMode === 'dev'}
setIsOpenSideViewDirects={setIsOpenSideViewDirects} setIsOpenSideViewDirects={setIsOpenSideViewDirects}
setIsOpenSideViewGroups={setIsOpenSideViewGroups} setIsOpenSideViewGroups={setIsOpenSideViewGroups}
/> />
@ -2515,10 +2519,15 @@ export const Group = ({
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread || isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
groupsAnnHasUnread} /> groupsAnnHasUnread} />
)} )}
{!isMobile && (
<AppsDevMode toggleSideViewGroups={toggleSideViewGroups} toggleSideViewDirects={toggleSideViewDirects} goToHome={goToHome} mode={appsModeDev} setMode={setAppsModeDev} setDesktopSideView={setDesktopSideView} hasUnreadDirects={directChatHasUnread} show={desktopViewMode === "dev"} myName={userInfo?.name} isGroups={isOpenSideViewGroups}
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
groupsAnnHasUnread} />
)}
{!isMobile && !selectedGroup && {!isMobile && !selectedGroup &&
groupSection === "home" && desktopViewMode !== "apps" && ( groupSection === "home" && desktopViewMode !== "apps" && desktopViewMode !== "dev" && (
<HomeDesktop <HomeDesktop
refreshHomeDataFunc={refreshHomeDataFunc} refreshHomeDataFunc={refreshHomeDataFunc}
myAddress={myAddress} myAddress={myAddress}
@ -2543,7 +2552,7 @@ export const Group = ({
width: "31px", width: "31px",
// minWidth: "135px", // minWidth: "135px",
padding: "5px", padding: "5px",
display: (isMobile || desktopViewMode === 'apps') ? "none" : "flex", display: (isMobile || desktopViewMode === 'apps' || desktopViewMode === 'dev') ? "none" : "flex",
}} }}
> >

View File

@ -25,6 +25,8 @@ import { LoadingSnackbar } from "../Snackbar/LoadingSnackbar";
import { getFee } from "../../background"; import { getFee } from "../../background";
import { LoadingButton } from "@mui/lab"; import { LoadingButton } from "@mui/lab";
import { subscribeToEvent, unsubscribeFromEvent } from "../../utils/events"; import { subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
import { enabledDevModeAtom } from "../../atoms/global";
import { useRecoilState } from "recoil";
function a11yProps(index: number) { function a11yProps(index: number) {
return { return {
@ -81,6 +83,9 @@ export const Settings = ({
setOpen, setOpen,
}) => { }) => {
const [checked, setChecked] = React.useState(false); const [checked, setChecked] = React.useState(false);
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked); setChecked(event.target.checked);
@ -148,7 +153,7 @@ export const Settings = ({
<AppBar sx={{ position: "relative", bgcolor: "#232428" }}> <AppBar sx={{ position: "relative", bgcolor: "#232428" }}>
<Toolbar> <Toolbar>
<Typography sx={{ ml: 2, flex: 1 }} variant="h6" component="div"> <Typography sx={{ ml: 2, flex: 1 }} variant="h6" component="div">
General Settings General Settings
</Typography> </Typography>
<IconButton <IconButton
edge="start" edge="start"
@ -166,29 +171,35 @@ export const Settings = ({
flexGrow: 1, flexGrow: 1,
overflowY: "auto", overflowY: "auto",
color: "white", color: "white",
padding: '20px' padding: "20px",
flexDirection: 'column',
display: 'flex',
gap: '20px'
}} }}
> >
<FormControlLabel
<FormControlLabel sx={{
sx={{ color: "white",
color: 'white' }}
}} control={
control={<LocalNodeSwitch checked={checked} <LocalNodeSwitch checked={checked} onChange={handleChange} />
onChange={handleChange} />} }
label="Disable all push notifications" label="Disable all push notifications"
/> />
<FormControlLabel
sx={{
color: "white",
}}
control={
<LocalNodeSwitch checked={isEnabledDevMode} onChange={(e)=> {
setIsEnabledDevMode(e.target.checked)
localStorage.setItem('isEnabledDevMode', JSON.stringify(e.target.checked))
}} />
}
label="Enable dev mode"
/>
</Box> </Box>
</Dialog> </Dialog>
</React.Fragment> </React.Fragment>
); );
}; };