close nodes

This commit is contained in:
Michael Zhang 2024-05-27 20:45:20 -05:00
parent 4f503ac1a3
commit d445cf2a71
6 changed files with 42 additions and 18 deletions

View file

@ -22,7 +22,7 @@ export const nodesOpenedAtom = atom<OrderedSet<string>>(OrderedSet<string>());
function App() { function App() {
const nodesOpened = useAtomValue(nodesOpenedAtom); const nodesOpened = useAtomValue(nodesOpenedAtom);
const openNode = useOpenNode(); const { openNode } = useNodeControls();
// Open today's journal entry if it's not already opened // Open today's journal entry if it's not already opened
useEffect(() => { useEffect(() => {
@ -60,9 +60,14 @@ function App() {
export default App; export default App;
export function useOpenNode() { export function useNodeControls() {
const [nodesOpened, setNodesOpened] = useAtom(nodesOpenedAtom); const [nodesOpened, setNodesOpened] = useAtom(nodesOpenedAtom);
return (node_id: string) => { return {
openNode: (node_id: string) => {
setNodesOpened(nodesOpened.remove(node_id).add(node_id)); setNodesOpened(nodesOpened.remove(node_id).add(node_id));
},
closeNode: (node_id: string) => {
setNodesOpened(nodesOpened.remove(node_id));
},
}; };
} }

View file

@ -5,13 +5,13 @@ import { getVersion } from "@tauri-apps/api/app";
import ListIcon from "@mui/icons-material/List"; import ListIcon from "@mui/icons-material/List";
import { useSetAtom } from "jotai"; import { useSetAtom } from "jotai";
import { sidebarExpandedAtom } from "./Sidebar"; import { sidebarExpandedAtom } from "./Sidebar";
import { nodesOpenedAtom, useOpenNode } from "../App"; import { useNodeControls } from "../App";
import { useCallback } from "react"; import { useCallback } from "react";
const version = await getVersion(); const version = await getVersion();
export default function Header() { export default function Header() {
const openNode = useOpenNode(); const { openNode } = useNodeControls();
const setSidebarExpanded = useSetAtom(sidebarExpandedAtom); const setSidebarExpanded = useSetAtom(sidebarExpandedAtom);
const createNewJournalPage = useCallback(() => { const createNewJournalPage = useCallback(() => {
@ -40,14 +40,14 @@ export default function Header() {
type="button" type="button"
onClick={() => setSidebarExpanded((prev) => !prev)} onClick={() => setSidebarExpanded((prev) => !prev)}
> >
<ListIcon /> <ListIcon fontSize="inherit" />
</button> </button>
<div className={styles.brand}> <div className={styles.brand}>
<span className={styles.title}>Panorama</span> <span className={styles.title}>Panorama</span>
<span className={styles.version}>v{version}</span> <span className={styles.version}>v{version}</span>
</div> </div>
<button type="button" onClick={createNewJournalPage}> <button type="button" onClick={createNewJournalPage}>
<NoteAddIcon /> <NoteAddIcon fontSize="inherit" />
</button> </button>
<SearchBar /> <SearchBar />
</div> </div>

View file

@ -26,8 +26,7 @@
font-size: 0.6rem; font-size: 0.6rem;
display: flex; display: flex;
align-items: center; align-items: stretch;
gap: 6px;
padding: 0 6px; padding: 0 6px;
button { button {
@ -41,10 +40,15 @@
&:hover { &:hover {
background-color: rgba(0, 0, 0, 0.25); background-color: rgba(0, 0, 0, 0.25);
} }
&.closeButton:hover {
background-color: red;
color: white;
}
} }
span { span {
padding: 2px 0; padding: 6px;
} }
} }

View file

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import styles from "./NodeDisplay.module.scss"; import styles from "./NodeDisplay.module.scss";
import ReactTimeAgo from "react-time-ago"; import ReactTimeAgo from "react-time-ago";
import JournalPage from "./nodes/JournalPage";
import { getNode } from "../lib/getNode"; import { getNode } from "../lib/getNode";
import FirstPageIcon from "@mui/icons-material/FirstPage"; import FirstPageIcon from "@mui/icons-material/FirstPage";
import { useOpenNode } from "../App"; import MoreVertIcon from "@mui/icons-material/MoreVert";
import CloseIcon from "@mui/icons-material/Close";
import { useNodeControls } from "../App";
export interface NodeDisplayProps { export interface NodeDisplayProps {
id: string; id: string;
@ -48,7 +49,8 @@ export default function NodeDisplay({ id, idx }: NodeDisplayProps) {
} }
function NodeDisplayHeaderLoaded({ idx, id, data }) { function NodeDisplayHeaderLoaded({ idx, id, data }) {
const openNode = useOpenNode(); const { openNode, closeNode } = useNodeControls();
return ( return (
<> <>
{idx === 0 || ( {idx === 0 || (
@ -68,6 +70,19 @@ function NodeDisplayHeaderLoaded({ idx, id, data }) {
</> </>
)} )}
</span> </span>
<div className="spacer" />
<button type="button">
<MoreVertIcon fontSize="inherit" />
</button>
<button
type="button"
className={styles.closeButton}
onClick={() => closeNode(id)}
>
<CloseIcon fontSize="inherit" />
</button>
</> </>
); );
} }

View file

@ -14,7 +14,7 @@ import {
import { useDebounce } from "use-debounce"; import { useDebounce } from "use-debounce";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { atom, useAtom, useSetAtom } from "jotai"; import { atom, useAtom, useSetAtom } from "jotai";
import { nodesOpenedAtom, useOpenNode } from "../App"; import { useNodeControls } from "../App";
const searchQueryAtom = atom(""); const searchQueryAtom = atom("");
const showMenuAtom = atom(false); const showMenuAtom = atom(false);
@ -89,7 +89,7 @@ export default function SearchBar() {
function SearchMenu({ results }) { function SearchMenu({ results }) {
const setSearchQuery = useSetAtom(searchQueryAtom); const setSearchQuery = useSetAtom(searchQueryAtom);
const setShowMenu = useSetAtom(showMenuAtom); const setShowMenu = useSetAtom(showMenuAtom);
const openNode = useOpenNode(); const { openNode } = useNodeControls();
return ( return (
<div className={styles.searchResults}> <div className={styles.searchResults}>

View file

@ -3,13 +3,13 @@ import styles from "./Sidebar.module.scss";
import classNames from "classnames"; import classNames from "classnames";
import EmailIcon from "@mui/icons-material/Email"; import EmailIcon from "@mui/icons-material/Email";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import { useOpenNode } from "../App"; import { useNodeControls } from "../App";
export const sidebarExpandedAtom = atom(false); export const sidebarExpandedAtom = atom(false);
export default function Sidebar() { export default function Sidebar() {
const sidebarExpanded = useAtomValue(sidebarExpandedAtom); const sidebarExpanded = useAtomValue(sidebarExpandedAtom);
const openNode = useOpenNode(); const { openNode } = useNodeControls();
return ( return (
<div <div