New UI colors and changes

This commit is contained in:
Sacha Weatherstone
2022-01-15 22:11:55 +11:00
parent 5b10d4de59
commit 5f2503976d
13 changed files with 239 additions and 193 deletions
+9 -19
View File
@@ -3,13 +3,8 @@ import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { FiBell } from 'react-icons/fi';
import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus';
import { Connection } from '@components/Connection';
import { MobileNavToggle } from '@components/menu/buttons/MobileNavToggle';
import { Notifications } from '@components/menu/buttons/Notifications';
import { ThemeToggle } from '@components/menu/buttons/ThemeToggle';
import { Logo } from '@components/menu/Logo';
import { MobileNav } from '@components/menu/MobileNav';
import { Navigation } from '@components/menu/Navigation';
import { useRoute } from '@core/router';
import { requestNotificationPermission } from '@core/utils/notifications';
@@ -23,6 +18,7 @@ import { Settings } from '@pages/settings/Index';
import { ErrorFallback } from './components/ErrorFallback';
import { MapboxProvider } from './components/MapBox/MapboxProvider';
import { BottomNav } from './components/menu/BottomNav';
import { addNotification, removeNotification } from './core/slices/appSlice';
export const App = (): JSX.Element => {
@@ -65,27 +61,20 @@ export const App = (): JSX.Element => {
return (
<div className={`h-screen w-screen ${darkMode ? 'dark' : ''}`}>
<Connection />
<div className="flex flex-col h-full bg-gray-200 dark:bg-primaryDark">
<div className="flex flex-col h-full bg-gray-200 dark:bg-secondaryDark">
<div className="flex flex-shrink-0 overflow-hidden bg-primary dark:bg-primary">
<div className="w-full overflow-hidden bg-white border-b border-gray-300 md:mt-6 md:mx-6 md:py-2 md:rounded-t-3xl dark:border-gray-600 md:shadow-md dark:bg-primaryDark">
<div className="flex items-center justify-between h-12 px-4 md:px-6">
<div className="hidden md:flex">
<div className="w-full overflow-hidden bg-white border-b border-gray-300 dark:border-gray-600 md:shadow-md dark:bg-secondaryDark">
<div className="flex items-center justify-between h-12 px-4">
<div className="flex">
<Logo />
</div>
<Navigation className="hidden md:flex" />
<MobileNavToggle />
<div className="flex items-center space-x-2">
<DeviceStatus />
<Notifications />
<ThemeToggle />
</div>
<Navigation className="flex" />
</div>
</div>
</div>
<MobileNav />
<div className="flex flex-grow w-full min-h-0 md:px-6 md:mb-6">
<div className="flex w-full bg-gray-100 md:shadow-xl md:overflow-hidden dark:bg-secondaryDark md:rounded-b-3xl">
<div className="flex flex-grow w-full min-h-0">
<div className="flex w-full bg-gray-100 md:shadow-xl md:overflow-hidden dark:bg-secondaryDark">
<ErrorBoundary FallbackComponent={ErrorFallback}>
{route.name === 'messages' && <Messages />}
{route.name === 'nodes' && (
@@ -99,6 +88,7 @@ export const App = (): JSX.Element => {
</ErrorBoundary>
</div>
</div>
<BottomNav />
</div>
</div>
);
+97
View File
@@ -0,0 +1,97 @@
import React from 'react';
import {
FiBell,
FiBluetooth,
FiCpu,
FiGitBranch,
FiMoon,
FiSun,
FiWifi,
} from 'react-icons/fi';
import {
connType,
openConnectionModal,
setDarkModeEnabled,
} from '@app/core/slices/appSlice';
import { useAppDispatch } from '@hooks/useAppDispatch';
import { useAppSelector } from '@hooks/useAppSelector';
import { Types } from '@meshtastic/meshtasticjs';
// export interface BottomNavProps {
// }
export const BottomNav = (): JSX.Element => {
const dispatch = useAppDispatch();
const meshtasticState = useAppSelector((state) => state.meshtastic);
const appState = useAppSelector((state) => state.app);
// @ts-ignore define version string global
const version = window.__COMMIT_HASH__ as string;
return (
<div className="flex justify-between bg-white border-t border-gray-300 dark:bg-secondaryDark dark:border-gray-600">
<div
className={`flex p-1 cursor-pointer group w-min hover:bg-opacity-80 ${
[
Types.DeviceStatusEnum.DEVICE_CONNECTED,
Types.DeviceStatusEnum.DEVICE_CONFIGURED,
].includes(meshtasticState.deviceStatus)
? 'bg-primary'
: [
Types.DeviceStatusEnum.DEVICE_CONNECTING,
Types.DeviceStatusEnum.DEVICE_RECONNECTING,
Types.DeviceStatusEnum.DEVICE_CONFIGURING,
].includes(meshtasticState.deviceStatus)
? 'bg-yellow-400'
: 'bg-gray-400'
}`}
onClick={(): void => {
dispatch(dispatch(openConnectionModal()));
}}
>
{appState.connType === connType.BLE ? (
<FiBluetooth className="mr-1 p-0.5 group-active:scale-90" />
) : appState.connType === connType.SERIAL ? (
<FiCpu className="mr-1 p-0.5 group-active:scale-90" />
) : (
<FiWifi className="mr-1 p-0.5 group-active:scale-90" />
)}
<div className="text-xs font-medium truncate group-active:scale-90">
{meshtasticState.nodes.find(
(node) => node.number === meshtasticState.radio.hardware.myNodeNum,
)?.user?.longName ?? 'Disconnected'}
</div>
</div>
<div className="flex">
<a
href={`https://github.com/meshtastic/meshtastic-web/commit/${version}`}
target="_blank"
rel="noreferrer"
className="flex p-1 border-l border-gray-300 cursor-pointer select-none group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark"
>
<FiGitBranch className="p-0.5 mr-1 group-active:scale-90" />
<p className="text-xs opacity-60">{version}</p>
</a>
<div className="flex p-1 border-l border-gray-300 cursor-pointer select-none group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark">
<FiBell className="p-0.5 mr-1 group-active:scale-90" />
<p className="text-xs opacity-60">Example Notification</p>
</div>
<div
className="p-1 border-l border-gray-300 cursor-pointer group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark"
onClick={(): void => {
dispatch(setDarkModeEnabled(!appState.darkMode));
}}
>
{appState.darkMode ? (
<FiSun className="p-0.5 group-active:scale-90" />
) : (
<FiMoon className="p-0.5 group-active:scale-90" />
)}
</div>
</div>
</div>
);
};
-36
View File
@@ -1,36 +0,0 @@
import type React from 'react';
import { Drawer } from '@components/generic/Drawer';
import { closeMobileNav } from '@core/slices/appSlice';
import { useAppDispatch } from '@hooks/useAppDispatch';
import { useAppSelector } from '@hooks/useAppSelector';
import { Logo } from './Logo';
import { Navigation } from './Navigation';
export const MobileNav = (): JSX.Element => {
const dispatch = useAppDispatch();
const mobileNavOpen = useAppSelector((state) => state.app.mobileNavOpen);
return (
<Drawer
open={mobileNavOpen}
onClose={(): void => {
dispatch(closeMobileNav());
}}
className="z-50"
>
<div className="flex flex-col">
<div className="m-auto my-6">
<Logo />
</div>
<Navigation
onClick={(): void => {
dispatch(closeMobileNav());
}}
/>
</div>
</Drawer>
);
};
+53 -45
View File
@@ -1,9 +1,9 @@
import type React from 'react';
import { FiGrid, FiMessageSquare, FiPackage, FiSettings } from 'react-icons/fi';
import type { Link } from 'type-route';
import { routes, useRoute } from '@core/router';
import { Button } from '@meshtastic/components';
type DefaultDivProps = JSX.IntrinsicElements['div'];
@@ -15,51 +15,59 @@ export const Navigation = ({
...props
}: NavigationProps): JSX.Element => {
const route = useRoute();
return (
<div
className={`px-4 md:space-x-2 space-y-2 md:space-y-0 ${className}`}
{...props}
>
<div onClick={onClick}>
<Button
icon={<FiMessageSquare className="w-5 h-5" />}
active={route.name === 'messages'}
className="w-full md:w-auto"
{...routes.messages().link}
>
Messages
</Button>
</div>
<div onClick={onClick}>
<Button
icon={<FiGrid className="w-5 h-5" />}
className="w-full md:w-auto"
active={route.name === 'nodes'}
{...routes.nodes().link}
>
Nodes
</Button>
</div>
<div onClick={onClick}>
<Button
icon={<FiPackage className="w-5 h-5" />}
className="w-full md:w-auto"
active={route.name === 'plugins'}
{...routes.plugins().link}
>
Plugins
</Button>
</div>
<div onClick={onClick}>
<Button
icon={<FiSettings className="w-5 h-5" />}
className="w-full md:w-auto"
active={route.name === 'settings'}
{...routes.settings().link}
>
Settings
</Button>
</div>
<div className="flex h-full mt-2 border-t border-l border-r border-gray-300 rounded-t dark:text-white dark:border-gray-600">
<NavLink
name="Messages"
icon={
<FiMessageSquare className="w-5 h-5 my-auto group-active:scale-90" />
}
active={route.name === 'messages'}
link={routes.messages().link}
/>
<NavLink
name="Nodes"
icon={<FiGrid className="w-5 h-5 my-auto group-active:scale-90" />}
active={route.name === 'nodes'}
link={routes.nodes().link}
/>
<NavLink
name="Plugins"
icon={<FiPackage className="w-5 h-5 my-auto group-active:scale-90" />}
active={route.name === 'plugins'}
link={routes.plugins().link}
/>
<NavLink
name="Settings"
icon={<FiSettings className="w-5 h-5 my-auto group-active:scale-90" />}
active={route.name === 'settings'}
link={routes.settings().link}
/>
</div>
);
};
interface NavLinkProps {
name: string;
icon: JSX.Element;
active: boolean;
link: Link;
}
const NavLink = ({ name, icon, active, link }: NavLinkProps): JSX.Element => {
return (
<a
className={`flex h-full gap-1 p-2 cursor-pointer group hover:bg-gray-200 dark:hover:bg-primaryDark ${
active ? 'dark:bg-primaryDark bg-gray-200' : 'bg-transparent'
}`}
{...link}
>
{icon}
<div className="hidden my-auto md:flex">{name}</div>
</a>
);
};
@@ -1,28 +0,0 @@
import type React from 'react';
import { FiMoon, FiSun } from 'react-icons/fi';
import { setDarkModeEnabled } from '@core/slices/appSlice';
import { useAppDispatch } from '@hooks/useAppDispatch';
import { useAppSelector } from '@hooks/useAppSelector';
import { IconButton } from '@meshtastic/components';
export const ThemeToggle = (): JSX.Element => {
const dispatch = useAppDispatch();
const darkMode = useAppSelector((state) => state.app.darkMode);
return (
<IconButton
icon={
darkMode ? (
<FiSun className="w-5 h-5" />
) : (
<FiMoon className="w-5 h-5" />
)
}
onClick={(): void => {
dispatch(setDarkModeEnabled(!darkMode));
}}
/>
);
};
+4 -3
View File
@@ -1,6 +1,6 @@
import React from 'react';
import { FiXCircle } from 'react-icons/fi';
import { FiMenu, FiXCircle } from 'react-icons/fi';
import { Drawer } from '@components/generic/Drawer';
import type { SidebarItemProps } from '@components/generic/SidebarItem';
@@ -37,10 +37,11 @@ export const PageLayout = ({
}}
>
<Tab.List className="flex flex-col border-b border-gray-300 divide-y divide-gray-300 dark:divide-gray-600 dark:border-gray-600">
<div className="flex items-center justify-between m-6 mr-6">
<div className="text-4xl font-extrabold leading-none tracking-tight">
<div className="flex items-center justify-between m-4">
<div className="text-2xl font-extrabold leading-none tracking-tight">
{title}
</div>
<IconButton icon={<FiMenu />} />
<div className="md:hidden">
<IconButton
icon={<FiXCircle className="w-5 h-5" />}
+7 -1
View File
@@ -14,6 +14,8 @@ import { IconButton } from '@meshtastic/components';
import { NodeCard } from './NodeCard';
import { Sidebar } from './Sidebar';
// const getMarkerRadius = ():number => {}
export const Nodes = (): JSX.Element => {
const myNodeInfo = useAppSelector((state) => state.meshtastic.radio.hardware);
@@ -99,7 +101,11 @@ export const Nodes = (): JSX.Element => {
setSelectedNode(node);
setSidebarOpen(true);
}}
className="z-50 bg-blue-500 border-2 border-blue-500 rounded-full bg-opacity-30"
className={`z-50 border-2 rounded-full bg-opacity-30 ${
node.number === selectedNode?.number
? 'bg-green-500 border-green-500'
: 'bg-blue-500 border-blue-500'
}`}
>
<div className="m-4 ">
<FiMapPin className="w-5 h-5" />
+3 -3
View File
@@ -76,9 +76,9 @@ export const Sidebar = ({ node, closeSidebar }: SidebarProps): JSX.Element => {
<Tab.Panel className="p-2">Content 1</Tab.Panel>
<Tab.Panel className="p-2">
{node.currentPosition && (
<div className="flex justify-between h-10 px-1 bg-transparent border border-gray-300 rounded-md select-none dark:border-gray-600">
<div className="my-auto">
{(node.currentPosition.latitudeI / 1e7).toPrecision(6)},
<div className="flex justify-between h-10 px-1 text-gray-500 bg-transparent bg-gray-200 border border-gray-300 rounded-md select-none dark:border-gray-600 dark:bg-secondaryDark dark:text-gray-400 ">
<div className="px-1 my-auto">
{(node.currentPosition.latitudeI / 1e7).toPrecision(6)},&nbsp;
{(node.currentPosition?.longitudeI / 1e7).toPrecision(6)}
</div>
<IconButton
+1 -1
View File
@@ -74,7 +74,7 @@ export const Files = ({ navOpen, setNavOpen }: RangeTestProps): JSX.Element => {
{data.data.files.map((file: IFile) => (
<div
key={file.name}
className="flex justify-between mx-4 bg-gray-300 rounded-md dark:bg-gray-600 "
className="flex justify-between mx-4 bg-gray-300 rounded-md dark:bg-secondaryDark "
>
<div className="flex p-2 max-h-12">
<div className="flex w-12">