Skip to content

Commit

Permalink
feat: resizeable setting panel and adjust action tab
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Aug 1, 2024
1 parent 05a4c87 commit 5fd9b23
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 119 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"path-to-regexp": "7.1.0",
"posthog-js": "1.150.0",
"posthog-node": "4.0.1",
"re-resizable": "6.9.17",
"react-error-boundary": "4.0.13",
"react-fast-marquee": "1.6.5",
"react-hook-form": "7.52.1",
Expand Down
14 changes: 14 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 89 additions & 0 deletions src/renderer/src/components/ui/collapse/Collapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { cn } from "@renderer/lib/utils"
import type { Variants } from "framer-motion"
import { AnimatePresence, m } from "framer-motion"
import * as React from "react"

import { microReboundPreset } from "../constants/spring"

interface CollapseProps {
title: React.ReactNode
}
export const Collapse: Component<CollapseProps> = (props) => {
const [isOpened, setIsOpened] = React.useState(false)
return (
<CollapseControlled
isOpened={isOpened}
onOpenChange={setIsOpened}
{...props}
/>
)
}

export const CollapseControlled: Component<
{
isOpened: boolean
onOpenChange: (v: boolean) => void
} & CollapseProps
> = (props) => (
<div
className={cn("flex flex-col", props.className)}
data-state={props.isOpened ? "open" : "hidden"}
>
<div
className="relative flex w-full cursor-pointer items-center justify-between"
onClick={() => props.onOpenChange(!props.isOpened)}
>
<span className="w-0 shrink grow truncate">{props.title}</span>
<div className="shrink-0 text-gray-400">
<i
className={cn(
"i-mingcute-down-line duration-200",
props.isOpened ? "rotate-180" : "",
)}
/>
</div>
</div>
<CollapseContent isOpened={props.isOpened}>
{props.children}
</CollapseContent>
</div>
)
export const CollapseContent: Component<{
isOpened: boolean
withBackground?: boolean
}> = ({ isOpened, className, children }) => {
const variants = React.useMemo(() => {
const v = {
open: {
opacity: 1,
height: "auto",
transition: microReboundPreset,
},
collapsed: {
opacity: 0,
height: 0,
overflow: "hidden",
},
} satisfies Variants

return v
}, [])
return (
<>
<AnimatePresence initial={false}>
{isOpened && (
<m.div
key="content"
initial="collapsed"
animate="open"
exit="collapsed"
variants={variants}
className={className}
>
{children}
</m.div>
)}
</AnimatePresence>
</>
)
}
1 change: 1 addition & 0 deletions src/renderer/src/components/ui/collapse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Collapse"
160 changes: 76 additions & 84 deletions src/renderer/src/modules/settings/action-card.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { Button } from "@renderer/components/ui/button"
import { Card, CardHeader } from "@renderer/components/ui/card"
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@renderer/components/ui/collapsible"
import { Collapse, CollapseControlled } from "@renderer/components/ui/collapse"
import { Divider } from "@renderer/components/ui/divider"
import { Input } from "@renderer/components/ui/input"
import { Label } from "@renderer/components/ui/label"
import { Radio } from "@renderer/components/ui/radio-group"
import { RadioGroup } from "@renderer/components/ui/radio-group/RadioGroup"
import {
Expand All @@ -27,6 +22,7 @@ import {
TableRow,
} from "@renderer/components/ui/table"
import { ViewSelectContent } from "@renderer/components/view-select-content"
import { stopPropagation } from "@renderer/lib/dom"
import { cn } from "@renderer/lib/utils"
import type { SupportedLanguages } from "@renderer/models"

Expand Down Expand Up @@ -251,25 +247,33 @@ const OperationTableCell = ({

const SettingCollapsible = ({
title,
children,
open,
onOpenChange,
open,
children,
}: {
title: string
children: React.ReactNode
open?: boolean
onOpenChange?: (open: boolean) => void
}) => (
<Collapsible open={open} onOpenChange={onOpenChange}>
<div className="flex items-center">
<Label className="flex-1">{title}</Label>
<CollapsibleTrigger className="-m-3 flex items-center [&_i]:data-[state=open]:rotate-45">
<i className="i-mgc-add-cute-re m-3 transition-transform" />
</CollapsibleTrigger>
</div>
<CollapsibleContent className="mt-2">{children}</CollapsibleContent>
</Collapsible>
)
}) => {
if (typeof open === "boolean" && typeof onOpenChange === "function") {
return (
<CollapseControlled
isOpened={open}
onOpenChange={onOpenChange}
title={title}
>
<div className="pt-2">{children}</div>
</CollapseControlled>
)
}

return (
<Collapse title={title}>
<div className="pt-2">{children}</div>
</Collapse>
)
}

const CommonSelectTrigger = ({ className }: { className?: string }) => (
<SelectTrigger className={cn("h-8", className)}>
Expand All @@ -287,33 +291,36 @@ export function ActionCard({
return (
<Card>
<CardHeader className="space-y-4 px-6 py-4">
<Collapsible className="[&_.name-placeholder]:data-[state=open]:hidden [&_input.name-input]:data-[state=open]:block">
<div className="flex w-full items-center gap-2">
<Button
variant="ghost"
size="sm"
className="-ml-2"
onClick={() => {
onChange(null)
}}
>
<i className="i-mgc-delete-2-cute-re text-zinc-600" />
</Button>
<p className="shrink-0 font-medium text-zinc-500">Name</p>
<Input
value={data.name}
className="name-input hidden h-8"
onChange={(e) => {
data.name = e.target.value
onChange(data)
}}
/>
<CollapsibleTrigger className="flex w-14 flex-1 shrink-0 items-center pl-3 text-left [&_i]:data-[state=open]:rotate-90">
<Collapse
className="[&_.name-placeholder]:data-[state=open]:hidden [&_input.name-input]:data-[state=open]:block"
title={(
<div className="flex w-full items-center gap-2">
<Button
variant="ghost"
size="sm"
className="-ml-2"
onClick={() => {
onChange(null)
}}
>
<i className="i-mgc-delete-2-cute-re text-zinc-600" />
</Button>
<p className="shrink-0 font-medium text-zinc-500">Name</p>
<Input
value={data.name}
className="name-input hidden h-8"
onClick={stopPropagation}
onChange={(e) => {
data.name = e.target.value
onChange(data)
}}
/>

<div className="name-placeholder flex-1 text-sm">{data.name}</div>
<i className="i-mgc-right-cute-re h-8 shrink-0 text-xl transition-transform" />
</CollapsibleTrigger>
</div>
<CollapsibleContent className="mt-4 space-y-4">
</div>
)}
>
<div className="mt-4 space-y-4">
<div className="space-y-3">
<p className="font-medium text-zinc-500">When feeds match…</p>
<div className="flex flex-col gap-2">
Expand Down Expand Up @@ -421,22 +428,26 @@ export function ActionCard({
)}
</div>
<div className="space-y-4">
<p className="font-medium text-zinc-500">
Then do…
</p>
<p className="font-medium text-zinc-500">Then do…</p>
<div className="w-full space-y-4">
<SettingCollapsible
title="Translate into"
open={!!data.result.translation}
onOpenChange={(open) => {
if (open) {
data.result.translation = TransitionOptions[0].value
} else {
delete data.result.translation
}
onChange(data)
}}
>
<div className="flex w-full cursor-pointer items-center justify-between">
<span className="w-0 shrink grow truncate">
Generate summary using AI
</span>
<Switch
checked={data.result.summary}
onCheckedChange={(checked) => {
data.result.summary = checked
onChange(data)
}}
/>
</div>
<Divider />

<div className="flex w-full cursor-pointer items-center justify-between">
<span className="w-0 shrink grow truncate">
Translate into
</span>
<Select
value={data.result.translation}
onValueChange={(value) => {
Expand All @@ -453,29 +464,10 @@ export function ActionCard({
))}
</SelectContent>
</Select>
</SettingCollapsible>
<Divider />
<SettingCollapsible
title="Generate summary using AI"
open={data.result.summary !== undefined}
onOpenChange={(open) => {
if (open) {
data.result.summary = true
} else {
delete data.result.summary
}
onChange(data)
}}
>
<Switch
checked={data.result.summary}
onCheckedChange={(checked) => {
data.result.summary = checked
onChange(data)
}}
/>
</SettingCollapsible>
</div>

<Divider />

<SettingCollapsible
title="Rewrite Rules"
open={!!data.result.rewriteRules}
Expand Down Expand Up @@ -661,8 +653,8 @@ export function ActionCard({
</SettingCollapsible>
</div>
</div>
</CollapsibleContent>
</Collapsible>
</div>
</Collapse>
</CardHeader>
</Card>
)
Expand Down
Loading

0 comments on commit 5fd9b23

Please sign in to comment.