Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Bowen7 committed Mar 18, 2021
1 parent f248bb3 commit 744100a
Show file tree
Hide file tree
Showing 21 changed files with 115 additions and 79 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,5 @@ dist
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.vscode
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tabWidth": 2,
"semi": false
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useContext, useEffect, useCallback } from "react"
import React, { useState, useEffect, useCallback } from "react"
import { Spacer, Select, Code, AutoComplete } from "@geist-ui/react"
import RadioGroup from "@/components/radio-group"
import RangeOption from "@/components/range-option"
Expand All @@ -8,20 +8,19 @@ import { useDebounceInput } from "@/utils/hooks"
import { charactersOptions } from "./helper"
import { CharacterClassKey } from "@/parser/utils/character-class"
import { Character, ClassCharacter, Range } from "@/types"
import VisContext from "../../../context"
import { ActionTypes } from "@/redux/vis"
import { useMainReducer, MainActionTypes } from "@/redux"
import { classOptions } from "./helper"
type Prop = {
character: Character
id: string
}
const Characters: React.FC<Prop> = ({ character, id }) => {
const { dispatch } = useContext(VisContext)
const [, dispatch] = useMainReducer()

const [setString, stringBindings] = useDebounceInput(
(value: string) =>
dispatch({
type: ActionTypes.EDIT_CHARACTER,
type: MainActionTypes.EDIT_CHARACTER,
payload: {
val: {
type: "string",
Expand Down Expand Up @@ -64,7 +63,7 @@ const Characters: React.FC<Prop> = ({ character, id }) => {
return
}
dispatch({
type: ActionTypes.EDIT_CHARACTER,
type: MainActionTypes.EDIT_CHARACTER,
payload: {
val: val as Character,
},
Expand All @@ -78,7 +77,7 @@ const Characters: React.FC<Prop> = ({ character, id }) => {
value: value as string,
}
dispatch({
type: ActionTypes.EDIT_CHARACTER,
type: MainActionTypes.EDIT_CHARACTER,
payload: {
val,
},
Expand Down
File renamed without changes.
File renamed without changes.
18 changes: 7 additions & 11 deletions src/modules/vis/editor/index.tsx → src/modules/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import React, { useState, useEffect, useContext } from "react"
import React, { useState, useEffect } from "react"
import BookOpen from "@geist-ui/react-icons/bookOpen"
import Edit from "@geist-ui/react-icons/edit"
import { Tabs } from "@geist-ui/react"
import { ActionTypes } from "@/redux/vis"
import VisContext from "../context"
import { useMainReducer, MainActionTypes } from "@/redux/"
import EditTab from "./tabs/edit"
import LegendTab from "./tabs/legend"
import { useEventListener } from "../../../utils/hooks"
import { useEventListener } from "@/utils/hooks"

type Tab = "legend" | "edit"

const Editor: React.FC<{}> = () => {
const {
state: { selectedIds },
dispatch,
} = useContext(VisContext)
const [{ selectedIds }, dispatch] = useMainReducer()

const [tabValue, setTabValue] = useState<Tab>("legend")

Expand All @@ -28,9 +24,9 @@ const Editor: React.FC<{}> = () => {

const editDisabled = selectedIds.length === 0

const remove = () => dispatch({ type: ActionTypes.REMOVE })
const undo = () => dispatch({ type: ActionTypes.UNDO })
const redo = () => dispatch({ type: ActionTypes.REDO })
const remove = () => dispatch({ type: MainActionTypes.REMOVE })
const undo = () => dispatch({ type: MainActionTypes.UNDO })
const redo = () => dispatch({ type: MainActionTypes.REDO })

useEventListener("keydown", (e: Event) => {
const event = e as KeyboardEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import React, { useEffect, useState, useContext } from "react"
import React, { useEffect, useState } from "react"
import { Divider, Button, ButtonGroup, Fieldset, Spacer } from "@geist-ui/react"
import Characters from "../features/basic"
import Group from "../features/group"
import Expression from "../features/expression"
import Quantifier from "../features/quantifier"
import { getInfoFromNodes, genInitialNodesInfo } from "./helper"
import { GroupKind, NodesInfo, Node } from "@/types"
import { ActionTypes } from "@/redux/vis"
import { getNodesByIds } from "@/parser/visit"
import VisContext from "../../context"
import { useMainReducer, MainActionTypes } from "@/redux"

export type InsertDirection = "prev" | "next" | "branch"

const InfoItem: React.FC<{}> = () => {
const [nodes, setNodes] = useState<Node[]>([])
const {
state: { selectedIds, nodes: rootNodes },
dispatch,
} = useContext(VisContext)
const [{ selectedIds, nodes: rootNodes }, dispatch] = useMainReducer()

useEffect(() => setNodes(getNodesByIds(rootNodes, selectedIds)), [
rootNodes,
Expand All @@ -32,10 +28,10 @@ const InfoItem: React.FC<{}> = () => {
const { id, expression, group, character } = nodesInfo

const handleInsert = (direction: InsertDirection) =>
dispatch({ type: ActionTypes.INSERT, payload: { direction } })
dispatch({ type: MainActionTypes.INSERT, payload: { direction } })
const handleGroup = (groupType: string, groupName: string) =>
dispatch({
type: ActionTypes.GROUP,
type: MainActionTypes.GROUP,
payload: { groupType: groupType as GroupKind | "nonGroup", groupName },
})

Expand Down
File renamed without changes.
File renamed without changes.
29 changes: 26 additions & 3 deletions src/modules/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import React, { useCallback } from "react"
import Railroad from "@/modules/railroad"
import Editor from "@/modules/editor"
import { Node } from "@/types"
import { useMainReducer, MainActionTypes } from "@/redux"
const DEFAULT_REGEX = `/[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+(a|b)/`

const HomeProvider: React.FC<{}> = () => {
const Home: React.FC<{}> = () => {
const handleChange = useCallback((regex: string) => console.log(regex), [])
return <Railroad regex={DEFAULT_REGEX} onChange={handleChange} />
const [, dispatch] = useMainReducer()

const handleMount = useCallback(
(id: string, nodes: Node[]) =>
dispatch({
type: MainActionTypes.SET_ACTIVE_CHART,
payload: { id, nodes, selectedIds: [] },
}),
[dispatch]
)

return (
<>
<Railroad
regex={DEFAULT_REGEX}
onChange={handleChange}
onMount={handleMount}
/>
<Editor />
</>
)
}

export default HomeProvider
export default Home
41 changes: 25 additions & 16 deletions src/modules/railroad/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ import React, { useRef, useState, useEffect } from "react"
import { RenderVirtualNode, Node } from "@/types"
import Traverse from "./traverse"
import SvgContainer from "./svgContainer"
import { useMainReducer } from "@/redux"
import { useMainReducer, MainActionTypes } from "@/redux"
import { useEffectOnce } from "@/utils/hooks"
import parser from "@/parser"
import { nanoid } from "nanoid"
type Props = {
regex: string
onMount?: (id: string, nodes: Node[]) => void
onChange?: (regex: string) => void
}
const emptyArr: string[] = []
const Railroad: React.FC<Props> = ({ regex: propRegex, onChange }) => {
const Railroad: React.FC<Props> = ({ regex: propRegex, onChange, onMount }) => {
const [
{ nodes: propNodes, selectedIds: propSelectedIds, activeId: propActiveId },
dispatch,
] = useMainReducer()

const regex = useRef<string>("")
const regex = useRef<string>(propRegex)
const canvasRef = useRef<HTMLCanvasElement>(null)
const traverse = useRef<Traverse>(new Traverse(canvasRef))

const activeId = useRef<string>(nanoid())
const id = useRef<string>(nanoid())
const [nodes, setNodes] = useState<Node[]>([])
const [selectedIds, setSelectedIds] = useState<string[]>([])
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
const [rootRenderNode, setRootRenderNode] = useState<RenderVirtualNode>({
type: "virtual",
x: 0,
Expand All @@ -33,43 +33,52 @@ const Railroad: React.FC<Props> = ({ regex: propRegex, onChange }) => {
children: [],
})

useEffectOnce(() => {
onMount && onMount(id.current, nodes)
})

useEffect(() => {
if (propRegex !== regex.current) {
regex.current = propRegex
const nodes = parser.parse(propRegex)
setNodes(nodes)
if (propActiveId === id.current) {
dispatch({
type: MainActionTypes.SET_ACTIVE_CHART,
payload: { id: id.current, nodes, selectedIds: [] },
})
}
}
}, [propRegex])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [propRegex, propActiveId])

useEffect(() => {
if (activeId.current !== propActiveId) {
setSelectedIds(emptyArr)
if (id.current !== propActiveId) {
if (selectedIds.length > 0) {
setSelectedIds([])
}
return
}
setNodes(propNodes)
setSelectedIds(propSelectedIds)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [propNodes, propActiveId, propSelectedIds])

useEffect(() => {
console.log(nodes)
const rootRenderNode = traverse.current.render(nodes)
const { width, height } = rootRenderNode
regex.current = parser.gen(nodes)
onChange && onChange(regex.current)
setWidth(width)
setHeight(height)
setRootRenderNode(rootRenderNode)
}, [onChange, nodes])

return (
<>
{/* for measureText */}
<canvas
ref={canvasRef}
style={{ position: "absolute", top: "-9999px", left: "-9999px" }}
/>
<SvgContainer
width={width}
height={height}
rootRenderNode={rootRenderNode}
selectedIds={selectedIds}
/>
Expand Down
15 changes: 7 additions & 8 deletions src/modules/railroad/svgContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import React, { useState, useRef, useCallback, useContext } from "react"
import React, { useState, useRef, useCallback } from "react"
import { useEventListener } from "@/utils/hooks"
import { RenderNode, RenderConnect, Box, RenderVirtualNode } from "@/types"
import { Node } from "@/types"
import RailNode from "./node"
import Connect from "./connect"
import { MainActionTypes, useMainReducer } from "@/redux"
type Props = {
width: number
height: number
rootRenderNode: RenderVirtualNode
selectedIds: string[]
}
const SvgContainer: React.FC<Props> = props => {
const { width, height, rootRenderNode, selectedIds } = props
const [_, dispatch] = useMainReducer()
const SvgContainer: React.FC<Props> = (props) => {
const { rootRenderNode, selectedIds } = props
const { width, height } = rootRenderNode
const [, dispatch] = useMainReducer()
const dragging = useRef<boolean>(false)
const moving = useRef<boolean>(false)
const startX = useRef<number>(0)
Expand Down Expand Up @@ -160,7 +159,7 @@ const SvgContainer: React.FC<Props> = props => {
if (
nodeSelected &&
target.branches &&
selectedIds.every(selectedId => selectedId !== id)
selectedIds.every((selectedId) => selectedId !== id)
) {
nodeSelected = false
}
Expand Down Expand Up @@ -195,7 +194,7 @@ const SvgContainer: React.FC<Props> = props => {
return
}

children.forEach(item => {
children.forEach((item) => {
if (item.type === "node" && item.target.id === selectedHeadId) {
selected = true
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/vis/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useContext } from "react"
import { Input, Button } from "@geist-ui/react"
import VisContext from "./context"
import { ActionTypes } from "@/redux/vis"
import Editor from "./editor"
import Editor from "@/modules/editor"
// import Railroad from "./railroad"
import parser from "@/parser"

Expand Down
2 changes: 1 addition & 1 deletion src/redux/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useContext } from "react"
import { default as MainProvider, Context } from "./provider"
import { MainActionTypes } from "./reducer"
import { ActionTypes as MainActionTypes } from "./reducer"

export const useMainReducer = () => useContext(Context)

Expand Down
Loading

1 comment on commit 744100a

@vercel
Copy link

@vercel vercel bot commented on 744100a Mar 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.