From e5d7d7b5ad07677a7f971fcc6955a5bddec5de4d Mon Sep 17 00:00:00 2001
From: 0xzion <0xzion.penx@gmail.com>
Date: Thu, 25 Apr 2024 18:46:20 +0800
Subject: [PATCH] feat: improve settings ui in mobile
---
extensions/database/src/ui/TagDrawer.tsx | 1 +
packages/app/src/Workbench/BottomBar.tsx | 2 -
.../BottomBarDrawer/BottomBarDrawer.tsx | 46 ----
.../BottomBarDrawer/QuickAddEditor.tsx | 209 ------------------
.../Workbench/BottomBarDrawer/QuickAddTag.tsx | 43 ----
.../Workbench/BulletDrawer/BulletDrawer.tsx | 1 +
.../app/src/Workbench/NodeNav/MobileNav.tsx | 8 +
.../Workbench/PageSettings/PageSettings.tsx | 19 ++
.../Workbench/PageSettings/SettingsDrawer.tsx | 57 +++++
.../SettingsModal/SettingsSidebar.tsx | 84 +++++--
.../SpacePopover/SpacePopoverTrigger.tsx | 15 +-
.../Workbench/SidebarDrawer/SidebarDrawer.tsx | 1 +
packages/app/src/Workbench/Workbench.tsx | 2 +
packages/hooks/src/index.ts | 2 +-
packages/hooks/src/useBottomBarDrawer.ts | 12 -
packages/hooks/src/useSettingDrawer.ts | 27 +++
packages/store/src/stores/RouterStore.ts | 6 +
packages/store/src/types.ts | 1 +
18 files changed, 201 insertions(+), 335 deletions(-)
delete mode 100644 packages/app/src/Workbench/BottomBarDrawer/BottomBarDrawer.tsx
delete mode 100644 packages/app/src/Workbench/BottomBarDrawer/QuickAddEditor.tsx
delete mode 100644 packages/app/src/Workbench/BottomBarDrawer/QuickAddTag.tsx
create mode 100644 packages/app/src/Workbench/PageSettings/PageSettings.tsx
create mode 100644 packages/app/src/Workbench/PageSettings/SettingsDrawer.tsx
delete mode 100644 packages/hooks/src/useBottomBarDrawer.ts
create mode 100644 packages/hooks/src/useSettingDrawer.ts
diff --git a/extensions/database/src/ui/TagDrawer.tsx b/extensions/database/src/ui/TagDrawer.tsx
index 948717d8b..6a836b65b 100644
--- a/extensions/database/src/ui/TagDrawer.tsx
+++ b/extensions/database/src/ui/TagDrawer.tsx
@@ -36,6 +36,7 @@ export const TagDrawer = () => {
right-0
zIndex-101
autoFocus
+ outlineNone
// overflowHidden
>
diff --git a/packages/app/src/Workbench/BottomBar.tsx b/packages/app/src/Workbench/BottomBar.tsx
index 83bd7154f..3aca7fb00 100644
--- a/packages/app/src/Workbench/BottomBar.tsx
+++ b/packages/app/src/Workbench/BottomBar.tsx
@@ -10,7 +10,6 @@ import { useNodeContext } from '@penx/node-hooks'
import { store } from '@penx/store'
import { DailyShortcut, MotionButton } from '@penx/widget'
import { setStatusBarColor } from '../common/setStatusBarColor'
-import { BottomBarDrawer } from './BottomBarDrawer/BottomBarDrawer'
import { QuickAdd } from './QuickAdd/QuickAdd'
interface ActionButtonProps extends ButtonProps, FowerHTMLProps<'button'> {
@@ -46,7 +45,6 @@ export function BottomBar() {
return (
<>
-
diff --git a/packages/app/src/Workbench/BottomBarDrawer/BottomBarDrawer.tsx b/packages/app/src/Workbench/BottomBarDrawer/BottomBarDrawer.tsx
deleted file mode 100644
index cded51c85..000000000
--- a/packages/app/src/Workbench/BottomBarDrawer/BottomBarDrawer.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { styled } from '@fower/react'
-import { Drawer } from 'vaul'
-import { useBottomBarDrawer } from '@penx/hooks'
-import { QuickAddEditor } from './QuickAddEditor'
-
-const DrawerOverlay = styled(Drawer.Overlay)
-const DrawerContent = styled(Drawer.Content)
-
-export const BottomBarDrawer = () => {
- const { isOpen, close, open } = useBottomBarDrawer()
-
- return (
- {
- if (o) {
- open()
- } else {
- close()
- }
- }}
- >
-
-
-
-
-
-
-
- )
-}
diff --git a/packages/app/src/Workbench/BottomBarDrawer/QuickAddEditor.tsx b/packages/app/src/Workbench/BottomBarDrawer/QuickAddEditor.tsx
deleted file mode 100644
index 543d3bc1f..000000000
--- a/packages/app/src/Workbench/BottomBarDrawer/QuickAddEditor.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-import { useRef, useState } from 'react'
-import TextareaAutosize from 'react-textarea-autosize'
-import { Box, css } from '@fower/react'
-import { Clock, Hash, X } from 'lucide-react'
-import { Button, Checkbox, toast } from 'uikit'
-import { ELEMENT_P, ELEMENT_TAG, ELEMENT_TODO } from '@penx/constants'
-import { useBottomBarDrawer, useRouterStore } from '@penx/hooks'
-import { db, getCommonNode, getNewNode } from '@penx/local-db'
-import { Node } from '@penx/model'
-import { store } from '@penx/store'
-import { QuickAddTag } from './QuickAddTag'
-
-export const QuickAddEditor = () => {
- const { close } = useBottomBarDrawer()
- const ref = useRef(null)
-
- const [value, setValue] = useState('')
- const [isTodo, setIsTodo] = useState(false)
- const [databases, setDatabases] = useState([])
-
- const { isTodos } = useRouterStore()
-
- function selectTag(node: Node) {
- if (databases.map((d) => d.id).includes(node.id)) {
- setDatabases(databases.filter((d) => d.id !== node.id))
- } else {
- setDatabases([...databases, node])
- }
-
- ref.current?.focus()
- }
-
- async function addWithTags() {
- const spaceId = store.space.getActiveSpace().id
- const children: any[] = [{ text: value }, { text: ' ' }]
- const element: any = {
- type: isTodo ? ELEMENT_TODO : ELEMENT_P,
- children,
- }
- const divider = { text: ' ' }
-
- const tags = databases.map((d) => ({
- type: ELEMENT_TAG,
- databaseId: d.id,
- trigger: '#',
- name: d.tagName,
- isOpen: false,
- children: [{ text: '#' + d.tagName }],
- }))
-
- tags.forEach((tag, index) => {
- if (index === tags.length - 1) {
- children.push(...[tag, divider])
- // children.push(tag)
- } else {
- children.push(tag)
- }
- })
-
- const newNode = getCommonNode({
- spaceId,
- element,
- })
-
- const newTodayNode = await db.addNodesToToday(spaceId, [newNode])
-
- for (const tag of tags) {
- await db.createTagRow(spaceId, tag.name, newNode.id)
- }
-
- if (isTodo) {
- await db.createTodoRow(spaceId, newNode.id, newTodayNode.id)
- }
-
- const nodes = await db.listNodesBySpaceId(spaceId)
-
- store.node.setNodes(nodes)
- store.node.selectNode(newTodayNode)
- }
-
- async function send() {
- if (!value) return
-
- if (databases.length > 0) {
- addWithTags()
- } else {
- if (isTodo) {
- store.node.addTodo(value, isTodos())
- } else {
- store.node.addTextToToday(value)
- }
- }
- close()
- }
-
- return (
-
-
-
- {isTodo && (
-
-
-
-
-
- )}
-
- setValue(e.target.value)}
- />
-
-
- {databases.length > 0 && (
-
- {databases.map((node) => {
- return (
- selectTag(node)}
- >
- #{node.tagName}
-
-
-
-
- )
- })}
-
- )}
-
-
-
-
-
- {
- setIsTodo(e.target.checked)
- ref.current?.focus()
- }}
- />
-
-
-
-
- {
- toast.info('Coming soon!')
- }}
- >
-
-
- {/*
-
- */}
-
-
-
-
- {
- selectTag(node)
- }}
- />
-
-
- )
-}
diff --git a/packages/app/src/Workbench/BottomBarDrawer/QuickAddTag.tsx b/packages/app/src/Workbench/BottomBarDrawer/QuickAddTag.tsx
deleted file mode 100644
index 906c6f011..000000000
--- a/packages/app/src/Workbench/BottomBarDrawer/QuickAddTag.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Box } from '@fower/react'
-import { Node } from '@penx/model'
-import { useDatabaseNodes } from '@penx/node-hooks'
-
-interface Props {
- onSelect: (node: Node) => void
-}
-
-export const QuickAddTag = ({ onSelect }: Props) => {
- const nodes = useDatabaseNodes()
- return (
-
-
- Quick add a tag:
-
-
- {nodes.map((item) => {
- const node = new Node(item)
- if (node.isTodoDatabase) return null
- return (
- onSelect(node)}
- >
- #{node.tagName}
-
- )
- })}
-
-
- )
-}
diff --git a/packages/app/src/Workbench/BulletDrawer/BulletDrawer.tsx b/packages/app/src/Workbench/BulletDrawer/BulletDrawer.tsx
index 3df4e4dc6..bf1276d99 100644
--- a/packages/app/src/Workbench/BulletDrawer/BulletDrawer.tsx
+++ b/packages/app/src/Workbench/BulletDrawer/BulletDrawer.tsx
@@ -35,6 +35,7 @@ export const BulletDrawer = () => {
left-0
right-0
zIndex-101
+ outlineNone
autoFocus
>
diff --git a/packages/app/src/Workbench/NodeNav/MobileNav.tsx b/packages/app/src/Workbench/NodeNav/MobileNav.tsx
index ae54159f4..3dbc22dc6 100644
--- a/packages/app/src/Workbench/NodeNav/MobileNav.tsx
+++ b/packages/app/src/Workbench/NodeNav/MobileNav.tsx
@@ -11,6 +11,14 @@ function Title() {
const { activeNodes } = useActiveNodes()
const router = useRouterStore()
+ if (router.isSettings()) {
+ return (
+
+ Settings
+
+ )
+ }
+
if (router.isTodos()) {
return (
diff --git a/packages/app/src/Workbench/PageSettings/PageSettings.tsx b/packages/app/src/Workbench/PageSettings/PageSettings.tsx
new file mode 100644
index 000000000..5fa54b660
--- /dev/null
+++ b/packages/app/src/Workbench/PageSettings/PageSettings.tsx
@@ -0,0 +1,19 @@
+import { Box } from '@fower/react'
+import { WORKBENCH_NAV_HEIGHT } from '@penx/constants'
+import { SettingsSidebar } from '../SettingsModal/SettingsSidebar'
+import { SettingsDrawer } from './SettingsDrawer'
+
+export const PageSettings = () => {
+ return (
+
+
+
+
+ )
+}
diff --git a/packages/app/src/Workbench/PageSettings/SettingsDrawer.tsx b/packages/app/src/Workbench/PageSettings/SettingsDrawer.tsx
new file mode 100644
index 000000000..aab8f2897
--- /dev/null
+++ b/packages/app/src/Workbench/PageSettings/SettingsDrawer.tsx
@@ -0,0 +1,57 @@
+import { Box, styled } from '@fower/react'
+import { Drawer } from 'vaul'
+import { SettingsType } from '@penx/constants'
+import { useSettingDrawer } from '@penx/hooks'
+import { SyncServer } from '../../SyncServer/SyncServer'
+import { AccountSettings } from '../AccountSettings/AccountSettings'
+import { Backup } from '../Backup/Backup'
+import { RecoveryPhrase } from '../RecoveryPhrase/RecoveryPhrase'
+import { SpaceSettings } from '../SpaceSettings/SpaceSettings'
+
+const DrawerOverlay = styled(Drawer.Overlay)
+const DrawerContent = styled(Drawer.Content)
+
+export const SettingsDrawer = () => {
+ const { isOpen, type, spaceId, close, open } = useSettingDrawer()
+
+ return (
+ {
+ if (o) {
+ open(type, spaceId)
+ } else {
+ close()
+ }
+ }}
+ >
+
+
+
+ {type === SettingsType.ACCOUNT_SETTINGS && }
+ {type === SettingsType.RECOVERY_PHRASE && }
+ {type === SettingsType.SYNC_BACKUP && }
+ {type === SettingsType.SYNC_SERVER && }
+ {type === SettingsType.SPACE && }
+
+
+
+ )
+}
diff --git a/packages/app/src/Workbench/SettingsModal/SettingsSidebar.tsx b/packages/app/src/Workbench/SettingsModal/SettingsSidebar.tsx
index 8b0e195f7..ebbe4ab8b 100644
--- a/packages/app/src/Workbench/SettingsModal/SettingsSidebar.tsx
+++ b/packages/app/src/Workbench/SettingsModal/SettingsSidebar.tsx
@@ -1,6 +1,14 @@
import { useMemo } from 'react'
+import { isMobile } from 'react-device-detect'
import { Box, FowerHTMLProps, styled } from '@fower/react'
-import { Cloud, GitCompare, Key, LogOut, User } from 'lucide-react'
+import {
+ ChevronRightIcon,
+ Cloud,
+ GitCompare,
+ Key,
+ LogOut,
+ User,
+} from 'lucide-react'
import {
Avatar,
AvatarFallback,
@@ -10,11 +18,25 @@ import {
} from 'uikit'
import { isSyncEnabled, SettingsType } from '@penx/constants'
import { appEmitter } from '@penx/event'
-import { useSpaces, useUser } from '@penx/hooks'
+import { useSettingDrawer, useSpaces, useUser } from '@penx/hooks'
import { IconPassword } from '@penx/icons'
import { useSession } from '@penx/session'
-const Title = styled('div', ['gray400', 'mb4', 'textXS', 'uppercase'])
+const Title = styled('div', ['gray400', 'mb3', 'textXS', 'uppercase'])
+
+interface SectionProps extends FowerHTMLProps<'div'> {}
+function Section({ children, ...rest }: SectionProps) {
+ return (
+
+ {children}
+
+ )
+}
interface SidebarItemProps extends FowerHTMLProps<'div'> {
type: any
@@ -24,30 +46,48 @@ interface SidebarItemProps extends FowerHTMLProps<'div'> {
function SidebarItem({
type = SettingsType.PREFERENCES,
spaceId,
+ children,
...rest
}: SidebarItemProps) {
const { data = SettingsType.PREFERENCES, setData } = useModalContext<{
type: SettingsType
spaceId?: string
}>()
+
+ const settingDrawer = useSettingDrawer()
+
return (
{
+ if (isMobile) {
+ settingDrawer.open(type, spaceId!)
+ return
+ }
setData({ type, spaceId })
}}
- />
+ >
+
+ {children}
+
+
+
+
+
+
)
}
@@ -70,7 +110,14 @@ export const SettingsSidebar = () => {
const image = session?.user?.image || ''
return (
-
+
@@ -81,7 +128,7 @@ export const SettingsSidebar = () => {
General
-
+
Account settings
@@ -99,27 +146,28 @@ export const SettingsSidebar = () => {
{isSyncEnabled && (
-
+
Sync servers
)}
-
+
Space
-
- {spaces.map((space) => (
+
+ {spaces.map((space, index) => (
{space.name}
))}
-
+
@@ -128,7 +176,7 @@ export const SettingsSidebar = () => {
w-100p
colorScheme="red500"
gap2
- display={['none', 'none', 'flex']}
+ // display={['none', 'none', 'flex']}
onClick={async () => {
// await disconnectAsync()
// disconnect()
diff --git a/packages/app/src/Workbench/Sidebar/SpacePopover/SpacePopoverTrigger.tsx b/packages/app/src/Workbench/Sidebar/SpacePopover/SpacePopoverTrigger.tsx
index 38465010d..c6f7f574d 100644
--- a/packages/app/src/Workbench/Sidebar/SpacePopover/SpacePopoverTrigger.tsx
+++ b/packages/app/src/Workbench/Sidebar/SpacePopover/SpacePopoverTrigger.tsx
@@ -1,4 +1,5 @@
import { forwardRef } from 'react'
+import { isMobile } from 'react-device-detect'
import { Box } from '@fower/react'
import { ChevronsUpDown, Settings } from 'lucide-react'
import {
@@ -76,9 +77,15 @@ export const SpacePopoverTrigger = forwardRef(
opacity-100--$currentSpace--hover
onClick={(e) => {
close()
- modalController.open(ModalNames.SETTINGS, {
- type: SettingsType.ACCOUNT_SETTINGS,
- })
+
+ if (isMobile) {
+ store.router.routeTo('SETTINGS')
+ } else {
+ modalController.open(ModalNames.SETTINGS, {
+ type: SettingsType.ACCOUNT_SETTINGS,
+ })
+ }
+
drawer?.close?.()
e.stopPropagation()
}}
@@ -90,7 +97,7 @@ export const SpacePopoverTrigger = forwardRef(
isSquare
roundedFull
>
-
+
)}
diff --git a/packages/app/src/Workbench/SidebarDrawer/SidebarDrawer.tsx b/packages/app/src/Workbench/SidebarDrawer/SidebarDrawer.tsx
index d3551d606..3ed863c4f 100644
--- a/packages/app/src/Workbench/SidebarDrawer/SidebarDrawer.tsx
+++ b/packages/app/src/Workbench/SidebarDrawer/SidebarDrawer.tsx
@@ -104,6 +104,7 @@ export const SidebarDrawer = () => {
zIndex-101
// overflowHidden
// bgNeutral100
+ outlineNone
px4
py4
>
diff --git a/packages/app/src/Workbench/Workbench.tsx b/packages/app/src/Workbench/Workbench.tsx
index e4965ae32..708aa0935 100644
--- a/packages/app/src/Workbench/Workbench.tsx
+++ b/packages/app/src/Workbench/Workbench.tsx
@@ -17,6 +17,7 @@ import { BottomBar } from './BottomBar'
import { MobileNav } from './NodeNav/MobileNav'
import { PCNav } from './NodeNav/PCNav'
import { NodePanels } from './NodePanels'
+import { PageSettings } from './PageSettings/PageSettings'
import { PageTodo } from './PageTodo/PageTodo'
import { SettingsModal } from './SettingsModal/SettingsModal'
import { Sidebar } from './Sidebar/Sidebar'
@@ -95,6 +96,7 @@ export const Workbench = () => {
+ {name === 'SETTINGS' && }
{name === 'TODOS' && }
{name === 'WEB3_PROFILE' && }
{name === 'TASK_BOARD' && }
diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts
index 05f7022e2..377eea111 100644
--- a/packages/hooks/src/index.ts
+++ b/packages/hooks/src/index.ts
@@ -8,7 +8,7 @@ export * from './useCommands'
export * from './useSidebarDrawer'
export * from './usePaletteDrawer'
-export * from './useBottomBarDrawer'
+export * from './useSettingDrawer'
export * from './useBulletDrawer'
export * from './useQuickAdd'
diff --git a/packages/hooks/src/useBottomBarDrawer.ts b/packages/hooks/src/useBottomBarDrawer.ts
deleted file mode 100644
index 2b5d8308d..000000000
--- a/packages/hooks/src/useBottomBarDrawer.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { atom, useAtom } from 'jotai'
-
-const bottomBarDrawerAtom = atom(false)
-
-export function useBottomBarDrawer() {
- const [isOpen, setIsOpen] = useAtom(bottomBarDrawerAtom)
- return {
- isOpen,
- open: () => setIsOpen(true),
- close: () => setIsOpen(false),
- }
-}
diff --git a/packages/hooks/src/useSettingDrawer.ts b/packages/hooks/src/useSettingDrawer.ts
new file mode 100644
index 000000000..11986e0a1
--- /dev/null
+++ b/packages/hooks/src/useSettingDrawer.ts
@@ -0,0 +1,27 @@
+import { atom, useAtom } from 'jotai'
+import { SettingsType } from '@penx/constants'
+
+const settingDrawerAtom = atom({
+ isOpen: false,
+ type: SettingsType.ACCOUNT_SETTINGS,
+ spaceId: '',
+})
+
+export function useSettingDrawer() {
+ const [state, setState] = useAtom(settingDrawerAtom)
+ return {
+ ...state,
+ open: (type: SettingsType, spaceId: string) => {
+ setState({
+ isOpen: true,
+ type,
+ spaceId,
+ })
+ },
+ close: () =>
+ setState({
+ ...state,
+ isOpen: false,
+ }),
+ }
+}
diff --git a/packages/store/src/stores/RouterStore.ts b/packages/store/src/stores/RouterStore.ts
index ec6345821..d71db7838 100644
--- a/packages/store/src/stores/RouterStore.ts
+++ b/packages/store/src/stores/RouterStore.ts
@@ -44,11 +44,17 @@ export class RouterStore {
return routerName === 'TODOS'
}
+ isSettings = () => {
+ const routerName = this.getName()
+ return routerName === 'SETTINGS'
+ }
+
isShowMobileMenu = () => {
const routerName = this.getName()
return [
'TRASH',
'NODE',
+ 'SETTINGS',
'TODOS',
'CREATE_SPACE',
'WEB3_PROFILE',
diff --git a/packages/store/src/types.ts b/packages/store/src/types.ts
index f1df6cc33..f4a4bb505 100644
--- a/packages/store/src/types.ts
+++ b/packages/store/src/types.ts
@@ -6,6 +6,7 @@ export type RouteName =
| 'WEB3_PROFILE'
| 'TASK_BOARD'
| 'RESTORE_BACKUP'
+ | 'SETTINGS'
export type IRouterStore = {
name: RouteName