Working on refactoring to support router use case
This commit is contained in:
@@ -0,0 +1,128 @@
|
|||||||
|
import { useDrag } from 'react-use-gesture';
|
||||||
|
import { Route, Switch } from 'wouter';
|
||||||
|
|
||||||
|
import Store from '../store';
|
||||||
|
import * as actions from '../store/actions';
|
||||||
|
import * as selectors from '../store/selectors';
|
||||||
|
|
||||||
|
import App from '../components/ui/App';
|
||||||
|
import Backdrop from '../components/ui/Backdrop';
|
||||||
|
import Menu from '../components/ui/Menu';
|
||||||
|
import Modal from '../components/ui/Modal';
|
||||||
|
import Nav from '../components/ui/Nav';
|
||||||
|
import PageStack from '../components/ui/PageStack';
|
||||||
|
import Tab from '../components/ui/Tab';
|
||||||
|
import TabBar from '../components/ui/TabBar';
|
||||||
|
import { SafeAreaProvider } from '../components/ui/SafeArea';
|
||||||
|
import Notifications from '../components/Notifications';
|
||||||
|
import MenuContent from '../components/MenuContent';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import Home from './pages/Home';
|
||||||
|
import { cog, cogOutline, home, homeOutline, list, listOutline } from 'ionicons/icons';
|
||||||
|
|
||||||
|
const CurrentPage = ({ page }) => {
|
||||||
|
const currentPage = Store.useState(selectors.getCurrentPage);
|
||||||
|
|
||||||
|
// const Page = currentPage.component;
|
||||||
|
const Page = page;
|
||||||
|
|
||||||
|
const [local, setLocal] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLocal(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageStack>
|
||||||
|
{local ? (
|
||||||
|
<Switch>
|
||||||
|
<Route path="/" component={Home} />
|
||||||
|
</Switch>
|
||||||
|
) : (
|
||||||
|
<Page selected={true} />
|
||||||
|
)}
|
||||||
|
{/*pages.map(p => {
|
||||||
|
const Page = p.component;
|
||||||
|
return <Page selected={page.id === p.id} key={p.id} />;
|
||||||
|
})*/}
|
||||||
|
{/*<Page selected={true} />*/}
|
||||||
|
</PageStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppShell = ({ page }) => {
|
||||||
|
const showMenu = Store.useState(selectors.getMenuOpen);
|
||||||
|
const showNotifications = Store.useState(selectors.getNotificationsOpen);
|
||||||
|
const currentPage = Store.useState(selectors.getCurrentPage);
|
||||||
|
|
||||||
|
const closeMenu = () => actions.setMenuOpen(false);
|
||||||
|
|
||||||
|
const backdropClose = () => {
|
||||||
|
actions.setMenuOpen(false);
|
||||||
|
actions.setNotificationsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeNotifications = () => actions.setNotificationsOpen(false);
|
||||||
|
|
||||||
|
// To enable edge drag detection to open the side menu
|
||||||
|
const bind = useDrag(
|
||||||
|
({ down, movement: [mx], xy: [x, y], cancel }) => {
|
||||||
|
if (mx > 5 && x < 50 && down) {
|
||||||
|
actions.setMenuOpen(true);
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
axis: 'x',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// This is an example app layout. We've got a hidden menu that will be toggled
|
||||||
|
//
|
||||||
|
return (
|
||||||
|
<App
|
||||||
|
{...bind()}
|
||||||
|
style={{
|
||||||
|
touchAction: 'pan-x',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SafeAreaProvider>
|
||||||
|
<Menu open={showMenu} onClose={closeMenu}>
|
||||||
|
<MenuContent />
|
||||||
|
</Menu>
|
||||||
|
<Nav page={currentPage} />
|
||||||
|
{/*<CurrentPage page={currentPage} />*/}
|
||||||
|
<CurrentPage page={page} />
|
||||||
|
<TabBar>
|
||||||
|
<Tab
|
||||||
|
icon={homeOutline}
|
||||||
|
selectedIcon={home}
|
||||||
|
title="Home"
|
||||||
|
onClick={() => actions.setPage(p)}
|
||||||
|
selected={'home' === currentPage?.id}
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
icon={listOutline}
|
||||||
|
selectedIcon={list}
|
||||||
|
title="Lists"
|
||||||
|
onClick={() => actions.setPage(p)}
|
||||||
|
selected={'lists' === currentPage?.id}
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
icon={cogOutline}
|
||||||
|
selectedIcon={cog}
|
||||||
|
title="settings"
|
||||||
|
onClick={() => actions.setPage(p)}
|
||||||
|
selected={'settings' === currentPage?.id}
|
||||||
|
/>
|
||||||
|
</TabBar>
|
||||||
|
<Backdrop open={showMenu || showNotifications} onClose={backdropClose} />
|
||||||
|
<Modal open={showNotifications} onClose={closeNotifications}>
|
||||||
|
<Notifications />
|
||||||
|
</Modal>
|
||||||
|
</SafeAreaProvider>
|
||||||
|
</App>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppShell;
|
||||||
@@ -14,8 +14,6 @@ const MenuItem = ({ children, ...props }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const MenuContent = () => {
|
const MenuContent = () => {
|
||||||
const menuLinks = Store.useState(selectors.getMenuLinks);
|
|
||||||
|
|
||||||
const go = page => {
|
const go = page => {
|
||||||
actions.setPage(page);
|
actions.setPage(page);
|
||||||
actions.setMenuOpen(false);
|
actions.setMenuOpen(false);
|
||||||
@@ -27,15 +25,9 @@ const MenuContent = () => {
|
|||||||
<h2 className="text-xl select-none dark:text-gray-500">Menu</h2>
|
<h2 className="text-xl select-none dark:text-gray-500">Menu</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
{menuLinks.map(p => {
|
<MenuItem onClick={() => {}}>Home</MenuItem>
|
||||||
const title = typeof p.title === 'function' ? p.title() : p.title;
|
<MenuItem onClick={() => {}}>Lists</MenuItem>
|
||||||
|
<MenuItem onClick={() => {}}>Settings</MenuItem>
|
||||||
return (
|
|
||||||
<MenuItem key={p.id} onClick={() => go(p)}>
|
|
||||||
{title}
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import Card from '../ui/Card';
|
|||||||
import Content from '../ui/Content';
|
import Content from '../ui/Content';
|
||||||
|
|
||||||
import * as selectors from '../../store/selectors';
|
import * as selectors from '../../store/selectors';
|
||||||
|
import usePage from '../../hooks/usePage';
|
||||||
|
import { home, homeOutline } from 'ionicons/icons';
|
||||||
|
|
||||||
const HomeCard = ({ title, type, text, author, image }) => (
|
const HomeCard = ({ title, type, text, author, image }) => (
|
||||||
<Card className="my-4">
|
<Card className="my-4">
|
||||||
@@ -18,10 +20,17 @@ const HomeCard = ({ title, type, text, author, image }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const Home = ({ selected }) => {
|
const Home = ({ selected }) => {
|
||||||
|
usePage({
|
||||||
|
id: 'home',
|
||||||
|
title: 'Home',
|
||||||
|
icon: homeOutline,
|
||||||
|
selectedIcon: home,
|
||||||
|
});
|
||||||
|
|
||||||
const homeItems = Store.useState(selectors.getHomeItems);
|
const homeItems = Store.useState(selectors.getHomeItems);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Content visible={selected} className="p-4 dark:bg-black">
|
<Content visible={true} className="p-4 dark:bg-black">
|
||||||
{homeItems.map((i, index) => (
|
{homeItems.map((i, index) => (
|
||||||
<HomeCard {...i} key={index} />
|
<HomeCard {...i} key={index} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import * as actions from '../../store/actions';
|
|||||||
const Nav = ({ page }) => {
|
const Nav = ({ page }) => {
|
||||||
const [showProfileMenu, setShowProfileMenu] = useState(false);
|
const [showProfileMenu, setShowProfileMenu] = useState(false);
|
||||||
|
|
||||||
const title = typeof page.title === 'function' ? page.title() : page.title;
|
const title = typeof page?.title === 'function' ? page?.title() : page?.title || '';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Plugins.StatusBar.setStyle({
|
Plugins.StatusBar.setStyle({
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import Store from '../store';
|
||||||
|
|
||||||
|
const usePage = fields => {
|
||||||
|
useEffect(() => {
|
||||||
|
Store.update(s => {
|
||||||
|
s.currentPage = fields;
|
||||||
|
});
|
||||||
|
}, [fields]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default usePage;
|
||||||
Generated
+6
@@ -6233,6 +6233,12 @@
|
|||||||
"errno": "~0.1.7"
|
"errno": "~0.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"wouter": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wouter/-/wouter-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-+0KbaxtM8pcLZWH22oaatq1Rbtce+0KXnrGCjy/GSFPNs3pTyyL6nQoiPga+96LqO8SPnC8wy15jD7Ix/tZm1A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
|||||||
+2
-1
@@ -30,6 +30,7 @@
|
|||||||
"react-toggle": "^4.1.1",
|
"react-toggle": "^4.1.1",
|
||||||
"react-transition-group": "^4.4.1",
|
"react-transition-group": "^4.4.1",
|
||||||
"react-use-gesture": "^9.0.0-beta.11",
|
"react-use-gesture": "^9.0.0-beta.11",
|
||||||
"reselect": "^4.0.0"
|
"reselect": "^4.0.0",
|
||||||
|
"wouter": "^2.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-94
@@ -1,97 +1,6 @@
|
|||||||
import { useDrag } from 'react-use-gesture';
|
import AppShell from '../components/AppShell';
|
||||||
|
import Home from '../components/pages/Home';
|
||||||
import Store from '../store';
|
|
||||||
import * as actions from '../store/actions';
|
|
||||||
import * as selectors from '../store/selectors';
|
|
||||||
|
|
||||||
import App from '../components/ui/App';
|
|
||||||
import Backdrop from '../components/ui/Backdrop';
|
|
||||||
import Menu from '../components/ui/Menu';
|
|
||||||
import Modal from '../components/ui/Modal';
|
|
||||||
import Nav from '../components/ui/Nav';
|
|
||||||
import PageStack from '../components/ui/PageStack';
|
|
||||||
import Tab from '../components/ui/Tab';
|
|
||||||
import TabBar from '../components/ui/TabBar';
|
|
||||||
import { SafeAreaProvider } from '../components/ui/SafeArea';
|
|
||||||
import Notifications from '../components/Notifications';
|
|
||||||
import MenuContent from '../components/MenuContent';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
const CurrentPage = ({ page }) => {
|
|
||||||
const pages = Store.useState(selectors.getPages);
|
|
||||||
const currentPage = Store.useState(selectors.getCurrentPage);
|
|
||||||
|
|
||||||
const Page = currentPage.component;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PageStack>
|
|
||||||
{/*pages.map(p => {
|
|
||||||
const Page = p.component;
|
|
||||||
return <Page selected={page.id === p.id} key={p.id} />;
|
|
||||||
})*/}
|
|
||||||
<Page selected={true} />
|
|
||||||
</PageStack>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const showMenu = Store.useState(selectors.getMenuOpen);
|
return <AppShell page={Home} />;
|
||||||
const showNotifications = Store.useState(selectors.getNotificationsOpen);
|
|
||||||
const currentPage = Store.useState(selectors.getCurrentPage);
|
|
||||||
const tabs = Store.useState(selectors.getTabs);
|
|
||||||
|
|
||||||
const closeMenu = () => actions.setMenuOpen(false);
|
|
||||||
|
|
||||||
const backdropClose = () => {
|
|
||||||
actions.setMenuOpen(false);
|
|
||||||
actions.setNotificationsOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeNotifications = () => actions.setNotificationsOpen(false);
|
|
||||||
|
|
||||||
// To enable edge drag detection to open the side menu
|
|
||||||
const bind = useDrag(
|
|
||||||
({ down, movement: [mx], xy: [x, y], cancel }) => {
|
|
||||||
if (mx > 5 && x < 50 && down) {
|
|
||||||
actions.setMenuOpen(true);
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
axis: 'x',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// This is an example app layout. We've got a hidden menu that will be toggled
|
|
||||||
//
|
|
||||||
return (
|
|
||||||
<App
|
|
||||||
{...bind()}
|
|
||||||
style={{
|
|
||||||
touchAction: 'pan-x',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SafeAreaProvider>
|
|
||||||
<Menu open={showMenu} onClose={closeMenu}>
|
|
||||||
<MenuContent />
|
|
||||||
</Menu>
|
|
||||||
<Nav page={currentPage} />
|
|
||||||
<CurrentPage page={currentPage} />
|
|
||||||
<TabBar>
|
|
||||||
{tabs.map(p => (
|
|
||||||
<Tab
|
|
||||||
key={p.id}
|
|
||||||
{...p}
|
|
||||||
onClick={() => actions.setPage(p)}
|
|
||||||
selected={p.id === currentPage.id}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</TabBar>
|
|
||||||
<Backdrop open={showMenu || showNotifications} onClose={backdropClose} />
|
|
||||||
<Modal open={showNotifications} onClose={closeNotifications}>
|
|
||||||
<Notifications />
|
|
||||||
</Modal>
|
|
||||||
</SafeAreaProvider>
|
|
||||||
</App>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import AppShell from '../../components/AppShell';
|
||||||
|
import Home from '../../components/pages/Home';
|
||||||
|
|
||||||
|
export default function UserId() {
|
||||||
|
return <AppShell page={Home} />;
|
||||||
|
}
|
||||||
+1
-34
@@ -7,32 +7,6 @@ import Lists from '../components/pages/Lists';
|
|||||||
import Settings from '../components/pages/Settings';
|
import Settings from '../components/pages/Settings';
|
||||||
import ListDetail from '../components/pages/ListDetail';
|
import ListDetail from '../components/pages/ListDetail';
|
||||||
|
|
||||||
// The available pages here
|
|
||||||
const pages = [
|
|
||||||
{ id: 'home', title: 'Home', icon: homeOutline, selectedIcon: home, component: Home },
|
|
||||||
{
|
|
||||||
id: 'lists',
|
|
||||||
title: 'Lists',
|
|
||||||
icon: listOutline,
|
|
||||||
selectedIcon: list,
|
|
||||||
component: Lists,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'list-detail',
|
|
||||||
title: () => Store.getRawState().selectedList?.name,
|
|
||||||
icon: listOutline,
|
|
||||||
selectedIcon: list,
|
|
||||||
component: ListDetail,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'settings',
|
|
||||||
title: 'Settings',
|
|
||||||
icon: cogOutline,
|
|
||||||
selectedIcon: cog,
|
|
||||||
component: Settings,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const images = [
|
export const images = [
|
||||||
'https://images.unsplash.com/photo-1608091526083-86ae8489ae5c?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=2100&q=80',
|
'https://images.unsplash.com/photo-1608091526083-86ae8489ae5c?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=2100&q=80',
|
||||||
'https://images.unsplash.com/photo-1608050072262-7b26ba63fb46?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=2100&q=80',
|
'https://images.unsplash.com/photo-1608050072262-7b26ba63fb46?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=2100&q=80',
|
||||||
@@ -91,14 +65,7 @@ const Store = new PullStateStore({
|
|||||||
safeAreaBottom: 0,
|
safeAreaBottom: 0,
|
||||||
menuOpen: false,
|
menuOpen: false,
|
||||||
notificationsOpen: false,
|
notificationsOpen: false,
|
||||||
currentPage: pages[0],
|
currentPage: null,
|
||||||
pages,
|
|
||||||
|
|
||||||
// The pages that are linked to tabs
|
|
||||||
tabs: pages.filter(p => ['home', 'lists', 'settings'].indexOf(p.id) >= 0),
|
|
||||||
// The pages that are linked to the menu
|
|
||||||
menuLinks: pages.filter(p => ['home', 'lists', 'settings'].indexOf(p.id) >= 0),
|
|
||||||
|
|
||||||
homeItems,
|
homeItems,
|
||||||
lists,
|
lists,
|
||||||
selectedList: null,
|
selectedList: null,
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ const getState = state => state;
|
|||||||
export const getMenuOpen = createSelector(getState, state => state.menuOpen);
|
export const getMenuOpen = createSelector(getState, state => state.menuOpen);
|
||||||
export const getNotificationsOpen = createSelector(getState, state => state.notificationsOpen);
|
export const getNotificationsOpen = createSelector(getState, state => state.notificationsOpen);
|
||||||
export const getCurrentPage = createSelector(getState, state => state.currentPage);
|
export const getCurrentPage = createSelector(getState, state => state.currentPage);
|
||||||
export const getTabs = createSelector(getState, state => state.tabs);
|
|
||||||
export const getMenuLinks = createSelector(getState, state => state.menuLinks);
|
|
||||||
export const getPages = createSelector(getState, state => state.pages);
|
|
||||||
|
|
||||||
// App specific selectors
|
// App specific selectors
|
||||||
export const getHomeItems = createSelector(getState, state => state.homeItems);
|
export const getHomeItems = createSelector(getState, state => state.homeItems);
|
||||||
|
|||||||
Reference in New Issue
Block a user