Skip to content

Commit

Permalink
feat: improve command ux
Browse files Browse the repository at this point in the history
  • Loading branch information
0xzion committed May 16, 2024
1 parent 944a6f8 commit e50b193
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 87 deletions.
9 changes: 6 additions & 3 deletions apps/desktop/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ fn main() {
window.center().unwrap();
}
"Editor" => {
let window = app.get_window("dev_editor").unwrap();
// let window = app.get_window("dev_editor").unwrap();
let window = app.get_window("editor").unwrap();
window.emit("MenuEditorClicked", Some("Yes")).unwrap();
window.show().unwrap();
window.center().unwrap();
Expand All @@ -182,8 +183,10 @@ fn main() {

thread::spawn(move || start_server(*boxed_handle, *boxed_conn).unwrap());

let window = app.get_window("main").unwrap();
set_shadow(&window, true).expect("Unsupported platform!");
let main_window = app.get_window("main").unwrap();
set_shadow(&main_window, true).expect("Unsupported platform!");

main_window.show().unwrap();

Ok(())
})
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "PenX",
"version": "0.3.1"
"version": "0.3.7"
},
"tauri": {
"systemTray": {
Expand Down
180 changes: 97 additions & 83 deletions apps/desktop/src/components/CmdkRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { useRef, useState } from 'react'
import SVG from 'react-inlinesvg'
import Markdown from 'react-markdown'
import { Box, css, styled } from '@fower/react'
import { open } from '@tauri-apps/api/shell'
import { Command } from 'cmdk'
import { ArrowLeft } from 'lucide-react'
import Image from 'next/image'
import { EventType, ListItem } from 'penx'
import clipboard from 'tauri-plugin-clipboard-api'
// import { Command } from '@penx/cmdk'
import { db } from '@penx/local-db'
import { useCommandPosition } from '~/hooks/useCommandPosition'
import { useCurrentCommand } from '~/hooks/useCurrentCommand'
import { useInstallBuiltinExtension } from '~/hooks/useInstallBuiltinExtension'
import {
useCommands,
Expand All @@ -17,6 +19,7 @@ import {
useQueryCommands,
} from '~/hooks/useItems'
import { useReset } from '~/hooks/useReset'
import { CommandApp } from './CommandApp'

const StyledCommand = styled(Command)
const CommandInput = styled(Command.Input)
Expand Down Expand Up @@ -66,14 +69,21 @@ export const CmdkRoot = () => {
const { detail, setDetail } = useDetail()
const ref = useRef<HTMLInputElement>()

const { position, isRoot, isCommandApp, setPosition } = useCommandPosition()
const { currentCommand, setCurrentCommand } = useCurrentCommand()

useQueryCommands()
useInstallBuiltinExtension()

useReset(setQ)

async function handleSelect(item: ListItem, input = '') {
if (item.type === 'command') {
if (!q) setQ(item.title as string)
// if (!q) setQ(item.title as string)

setCurrentCommand(item)

setPosition('COMMAND_APP')

const ext = await db.getExtensionBySlug(item.data.extensionSlug)
if (!ext) return
Expand Down Expand Up @@ -119,8 +129,6 @@ export const CmdkRoot = () => {
if (event.data?.type === EventType.RenderMarkdown) {
const content = event.data.content as string
setDetail(content)
setItems([])
console.log('event......:', event)
}
}
}
Expand Down Expand Up @@ -167,91 +175,97 @@ export const CmdkRoot = () => {
return 1
}}
>
<CommandInput
ref={ref as any}
id="searchBarInput"
selectNone
toCenterY
bgTransparent
w-100p
h-54
px3
placeholderGray400
textBase
borderBottom
borderGray200
outlineNone
placeholder="Search something..."
autoFocus
value={q}
onValueChange={(v) => {
setQ(v)
if (v === '') {
setItems(commands)
setDetail('')
}
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
const [a, b = ''] = splitStringByFirstSpace(q)
const item = commands.find((item) => item.title === a)
if (item) {
handleSelect(item, String(b))
}
}
}}
/>
<Box flex-1>
{detail && (
<Box p4>
<Markdown>{detail}</Markdown>
<Box toCenterY>
{isCommandApp && (
<Box pl3 mr--8>
<ArrowLeft size={20}></ArrowLeft>
</Box>
)}
<CommandList flex-1 p2={!detail}>
{!detail && <Command.Empty>No results found.</Command.Empty>}

<CommandInput
ref={ref as any}
id="searchBarInput"
flex-1
selectNone
toCenterY
bgTransparent
w-100p
h-54
px3
placeholderGray400
textBase
borderBottom
borderGray200
outlineNone
placeholder="Search something..."
autoFocus
value={q}
onValueChange={(v) => {
setQ(v)
if (v === '') {
setItems(commands)
setDetail('')
}
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
// const [a, b = ''] = splitStringByFirstSpace(q)
// const item = commands.find((item) => item.title === a)
// if (item) {
// handleSelect(item, String(b))
// }
if (!q && isCommandApp) {
setPosition('ROOT')
}
}
}}
/>
</Box>
<Box flex-1>
{isCommandApp && currentCommand && <CommandApp />}
<CommandList flex-1 p2>
<Command.Group>
{items.map((item, index) => {
const title =
typeof item.title === 'string' ? item.title : item.title.value
{isRoot &&
items.map((item, index) => {
const title =
typeof item.title === 'string' ? item.title : item.title.value

const subtitle =
typeof item.subtitle === 'string'
? item.subtitle
: item.subtitle?.value
const subtitle =
typeof item.subtitle === 'string'
? item.subtitle
: item.subtitle?.value

return (
<CommandItem
key={index}
cursorPointer
toCenterY
toBetween
px2
py3
gap2
roundedLG
black
value={title}
onSelect={() => {
handleSelect(item)
}}
onClick={() => {
handleSelect(item)
}}
>
<Box toCenterY gap2>
<ItemIcon icon={item.icon as string}></ItemIcon>
<Box text-15>{title}</Box>
<Box textSM gray500>
{subtitle}
return (
<CommandItem
key={index}
cursorPointer
toCenterY
toBetween
px2
py3
gap2
roundedLG
black
value={title}
onSelect={() => {
handleSelect(item)
}}
onClick={() => {
handleSelect(item)
}}
>
<Box toCenterY gap2>
<ItemIcon icon={item.icon as string}></ItemIcon>
<Box text-15>{title}</Box>
<Box textSM gray500>
{subtitle}
</Box>
</Box>
<Box textXS gray400>
Command
</Box>
</Box>
<Box textXS gray400>
Command
</Box>
</CommandItem>
)
})}
</CommandItem>
)
})}
</Command.Group>
</CommandList>
</Box>
Expand Down
23 changes: 23 additions & 0 deletions apps/desktop/src/components/CommandApp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Markdown from 'react-markdown'
import { Box } from '@fower/react'
import { useCurrentCommand } from '~/hooks/useCurrentCommand'
import { useDetail } from '~/hooks/useItems'

interface CommandAppProps {
// detail: string
}
export function CommandApp({}: CommandAppProps) {
const { currentCommand } = useCurrentCommand()
const { detail } = useDetail()
console.log('======currentCommand:', currentCommand)

return (
<Box>
{detail && (
<Box p4>
<Markdown>{detail}</Markdown>
</Box>
)}
</Box>
)
}
15 changes: 15 additions & 0 deletions apps/desktop/src/hooks/useCommandPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { atom, useAtom } from 'jotai'

type Position = 'ROOT' | 'COMMAND_APP'

export const positionAtom = atom<Position>('ROOT')

export function useCommandPosition() {
const [position, setPosition] = useAtom(positionAtom)
return {
isRoot: position === 'ROOT',
isCommandApp: position === 'COMMAND_APP',
position,
setPosition,
}
}
9 changes: 9 additions & 0 deletions apps/desktop/src/hooks/useCurrentCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { atom, useAtom } from 'jotai'
import { ListItem } from 'penx'

export const currentCommandAtom = atom<ListItem>(null as any as ListItem)

export function useCurrentCommand() {
const [currentCommand, setCurrentCommand] = useAtom(currentCommandAtom)
return { currentCommand, setCurrentCommand }
}

0 comments on commit e50b193

Please sign in to comment.