diff --git a/src/App.tsx b/src/App.tsx
index eaca680..77f32c5 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -103,6 +103,7 @@ import { useQortalGetSaveSettings } from "./useQortalGetSaveSettings";
import { useRecoilState, useResetRecoilState, useSetRecoilState } from "recoil";
import {
canSaveSettingToQdnAtom,
+ enabledDevModeAtom,
fullScreenAtom,
hasSettingsChangedAtom,
oldPinnedAppsAtom,
@@ -370,9 +371,17 @@ function App() {
useRetrieveDataLocalStorage();
useQortalGetSaveSettings(userInfo?.name);
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
+ const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
+ useEffect(()=> {
+ const isDevModeFromStorage = localStorage.getItem('isEnabledDevMode');
+ if(isDevModeFromStorage){
+ setIsEnabledDevMode(JSON.parse(isDevModeFromStorage))
+ }
+ }, [])
+
useEffect(() => {
// Attach a global event listener for double-click
const handleDoubleClick = () => {
@@ -1519,7 +1528,7 @@ function App() {
desktopViewMode={desktopViewMode}
setDesktopViewMode={setDesktopViewMode}
/>
- {!isMobile && desktopViewMode !== "apps" && renderProfile()}
+ {!isMobile && desktopViewMode !== "apps" && desktopViewMode !== "dev" && renderProfile()}
{
+export const AppViewer = React.forwardRef(({ app , hide, isDevMode}, iframeRef) => {
const { rootHeight } = useContext(MyContext);
// const iframeRef = useRef(null);
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('')
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 : ''}`)
}, [app?.service, app?.name, app?.identifier, app?.path])
const defaultUrl = useMemo(()=> {
return url
- }, [url])
+ }, [url, isDevMode])
const refreshAppFunc = (e) => {
const {tabId} = e.detail
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()}`
setUrl(constructUrl)
}
@@ -41,7 +51,7 @@ export const AppViewer = React.forwardRef(({ app , hide}, iframeRef) => {
return () => {
unsubscribeFromEvent("refreshApp", refreshAppFunc);
};
- }, [app, path]);
+ }, [app, path, isDevMode]);
// Function to navigate back in iframe
const navigateBackInIframe = async () => {
diff --git a/src/components/Apps/AppViewerContainer.tsx b/src/components/Apps/AppViewerContainer.tsx
index 51bc0ff..27be01f 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, isMobile } from '../../App';
-const AppViewerContainer = React.forwardRef(({ app, isSelected, hide }, ref) => {
+const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode }, ref) => {
const { rootHeight } = useContext(MyContext);
@@ -42,7 +42,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide }, ref) =>
overflow: 'hidden',
}}
>
-
+
);
});
diff --git a/src/components/Apps/AppsDevMode.tsx b/src/components/Apps/AppsDevMode.tsx
new file mode 100644
index 0000000..4930d50
--- /dev/null
+++ b/src/components/Apps/AppsDevMode.tsx
@@ -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 (
+
+
+
+ {
+ goToHome();
+
+ }}
+ >
+
+
+
+
+ {
+ setDesktopSideView("directs");
+ toggleSideViewDirects()
+ }}
+ >
+
+
+
+
+ {
+ setDesktopSideView("groups");
+ toggleSideViewGroups()
+ }}
+ >
+
+
+
+
+ {mode !== 'home' && (
+
+
+ )}
+
+
+
+
+ {mode === "home" && (
+
+
+
+
+
+ )}
+
+
+
+
+ {tabs.map((tab) => {
+ if (!iframeRefs.current[tab.tabId]) {
+ iframeRefs.current[tab.tabId] = React.createRef();
+ }
+ return (
+
+ );
+ })}
+
+ {isNewTabWindow && mode === "viewer" && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+ );
+};
diff --git a/src/components/Apps/AppsDevModeHome.tsx b/src/components/Apps/AppsDevModeHome.tsx
new file mode 100644
index 0000000..3ffeccf
--- /dev/null
+++ b/src/components/Apps/AppsDevModeHome.tsx
@@ -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 (
+ <>
+
+
+ Dev Mode Apps
+
+
+
+
+ {
+ addDevModeApp();
+ }}
+ >
+
+
+ +
+
+ App
+
+
+
+ {isShow && (
+
+ )}
+ >
+ );
+};
diff --git a/src/components/Apps/AppsDevModeNavBar.tsx b/src/components/Apps/AppsDevModeNavBar.tsx
new file mode 100644
index 0000000..11b626c
--- /dev/null
+++ b/src/components/Apps/AppsDevModeNavBar.tsx
@@ -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 (
+
+
+ {
+ executeEvent("devModeNavigateBack", selectedTab?.tabId);
+ }}
+ disabled={isDisableBackButton}
+ sx={{
+ opacity: !isDisableBackButton ? 1 : 0.1,
+ cursor: !isDisableBackButton ? 'pointer': 'default'
+ }}
+ >
+
+
+
+ {tabs?.map((tab) => (
+
+ } // Pass custom component
+ sx={{
+ "&.Mui-selected": {
+ color: "white",
+ },
+ padding: "0px",
+ margin: "0px",
+ minWidth: "0px",
+ width: "50px",
+ }}
+ />
+ ))}
+
+
+ {selectedTab && (
+
+ {
+ setSelectedTab(null);
+ executeEvent("devModeNewTabWindow", {});
+ }}
+ >
+
+
+ {
+ if (!selectedTab) return;
+ handleClick(e);
+ }}
+ >
+
+
+
+ )}
+
+
+
+ );
+};
diff --git a/src/components/Apps/AppsDevModeTabComponent.tsx b/src/components/Apps/AppsDevModeTabComponent.tsx
new file mode 100644
index 0000000..174ef73
--- /dev/null
+++ b/src/components/Apps/AppsDevModeTabComponent.tsx
@@ -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 (
+ {
+ if(isSelected){
+ executeEvent('removeTab', {
+ data: app
+ })
+ return
+ }
+ executeEvent('setSelectedTab', {
+ data: app
+ })
+ }}>
+
+ {isSelected && (
+
+
+
+ ) }
+
+
+
+
+
+ )
+}
+
diff --git a/src/components/Apps/AppsHomeDesktop.tsx b/src/components/Apps/AppsHomeDesktop.tsx
index e7346ff..6481871 100644
--- a/src/components/Apps/AppsHomeDesktop.tsx
+++ b/src/components/Apps/AppsHomeDesktop.tsx
@@ -12,8 +12,8 @@ import { Add } from "@mui/icons-material";
import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events";
-import { SortablePinnedApps } from "./SortablePinnedApps";
import { Spacer } from "../../common/Spacer";
+import { SortablePinnedApps } from "./SortablePinnedApps";
export const AppsHomeDesktop = ({
setMode,
diff --git a/src/components/Apps/useQortalMessageListener.tsx b/src/components/Apps/useQortalMessageListener.tsx
index d5abebf..210ee91 100644
--- a/src/components/Apps/useQortalMessageListener.tsx
+++ b/src/components/Apps/useQortalMessageListener.tsx
@@ -383,7 +383,7 @@ const UIQortalRequests = [
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 [history, setHistory] = useState({
customQDNHistoryPaths: [],
@@ -530,7 +530,7 @@ isDOMContentLoaded: false
setHistory(event?.data?.payload)
}
- } else if(event?.data?.action === 'SET_TAB'){
+ } else if(event?.data?.action === 'SET_TAB' && !isDevMode){
executeEvent("addTab", {
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
diff --git a/src/components/Desktop/DesktopFooter.tsx b/src/components/Desktop/DesktopFooter.tsx
index f1cf754..70b7e5b 100644
--- a/src/components/Desktop/DesktopFooter.tsx
+++ b/src/components/Desktop/DesktopFooter.tsx
@@ -17,6 +17,8 @@ import AppIcon from "../../assets/svgs/AppIcon.svg";
import { HomeIcon } from "../../assets/Icons/HomeIcon";
import { Save } from "../Save/Save";
+import { useRecoilState } from "recoil";
+import { enabledDevModeAtom } from "../../atoms/global";
export const IconWrapper = ({ children, label, color, selected }) => {
return (
@@ -81,7 +83,8 @@ export const DesktopFooter = ({
setIsOpenSideViewGroups
}) => {
-
+ const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
+
if(hide) return
return (
+ {isEnabledDevMode && (
+ {
+ setDesktopViewMode('dev')
+ setIsOpenSideViewDirects(false)
+ setIsOpenSideViewGroups(false)
+ }}
+ >
+
+
+
+
+ )}
+
);
diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx
index 05f88b1..82f4359 100644
--- a/src/components/Group/Group.tsx
+++ b/src/components/Group/Group.tsx
@@ -91,6 +91,7 @@ import { DesktopHeader } from "../Desktop/DesktopHeader";
import { Apps } from "../Apps/Apps";
import { AppsNavBar } from "../Apps/AppsNavBar";
import { AppsDesktop } from "../Apps/AppsDesktop";
+import { AppsDevMode } from "../Apps/AppsDevMode";
// let touchStartY = 0;
// let disablePullToRefresh = false;
@@ -437,6 +438,7 @@ export const Group = ({
const initiatedGetMembers = useRef(false);
const [groupChatTimestamps, setGroupChatTimestamps] = React.useState({});
const [appsMode, setAppsMode] = useState('home')
+ const [appsModeDev, setAppsModeDev] = useState('home')
const [isOpenSideViewDirects, setIsOpenSideViewDirects] = useState(false)
const [isOpenSideViewGroups, setIsOpenSideViewGroups] = useState(false)
const toggleSideViewDirects = ()=> {
@@ -1553,6 +1555,8 @@ export const Group = ({
}
};
+ console.log('desktopViewMode', desktopViewMode)
+
const renderDirects = () => {
return (
- {!isMobile && ((desktopSideView === 'groups' && desktopViewMode !== 'apps') || isOpenSideViewGroups) && renderGroups()}
- {!isMobile && ((desktopSideView === 'directs' && desktopViewMode !== 'apps') || isOpenSideViewDirects) && renderDirects()}
+ {!isMobile && ((desktopSideView === 'groups' && desktopViewMode !== 'apps' && desktopViewMode !== 'dev') || isOpenSideViewGroups) && renderGroups()}
+ {!isMobile && ((desktopSideView === 'directs' && desktopViewMode !== 'apps' && desktopViewMode !== 'dev') || isOpenSideViewDirects) && renderDirects()}
@@ -2515,10 +2519,15 @@ export const Group = ({
isDirects={isOpenSideViewDirects} hasUnreadGroups={groupChatHasUnread ||
groupsAnnHasUnread} />
)}
+ {!isMobile && (
+
+ )}
{!isMobile && !selectedGroup &&
- groupSection === "home" && desktopViewMode !== "apps" && (
+ groupSection === "home" && desktopViewMode !== "apps" && desktopViewMode !== "dev" && (
diff --git a/src/components/Group/Settings.tsx b/src/components/Group/Settings.tsx
index 945ec70..f14483c 100644
--- a/src/components/Group/Settings.tsx
+++ b/src/components/Group/Settings.tsx
@@ -25,6 +25,8 @@ import { LoadingSnackbar } from "../Snackbar/LoadingSnackbar";
import { getFee } from "../../background";
import { LoadingButton } from "@mui/lab";
import { subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
+import { enabledDevModeAtom } from "../../atoms/global";
+import { useRecoilState } from "recoil";
function a11yProps(index: number) {
return {
@@ -81,6 +83,9 @@ export const Settings = ({
setOpen,
}) => {
const [checked, setChecked] = React.useState(false);
+ const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom)
+
+
const handleChange = (event: React.ChangeEvent) => {
setChecked(event.target.checked);
@@ -148,7 +153,7 @@ export const Settings = ({
- General Settings
+ General Settings
-
- }
- label="Disable all push notifications"
- />
-
-
-
-
-
-
+
+ }
+ label="Disable all push notifications"
+ />
+ {
+ setIsEnabledDevMode(e.target.checked)
+ localStorage.setItem('isEnabledDevMode', JSON.stringify(e.target.checked))
+ }} />
+ }
+ label="Enable dev mode"
+ />
-
-
-
);
};