Skip to content

Commit

Permalink
feat: action page (RSSNext#2006)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyoban authored Dec 12, 2024
1 parent 0ae6ec9 commit 6d9212e
Show file tree
Hide file tree
Showing 19 changed files with 1,089 additions and 903 deletions.
65 changes: 65 additions & 0 deletions apps/renderer/src/modules/action/action-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Button } from "@follow/components/ui/button/index.js"
import { Card, CardContent, CardHeader } from "@follow/components/ui/card/index.jsx"
import { Input } from "@follow/components/ui/input/index.js"
import { Switch } from "@follow/components/ui/switch/index.jsx"
import { useTranslation } from "react-i18next"

import { actionActions, useActionByIndex } from "~/store/action"

import { FeedFilter } from "./feed-filter"
import { TargetActionList } from "./target-action-list"

export const ActionCard = ({ index }: { index: number }) => {
return (
<Card>
<CardHeader>
<ActionCardToolbar index={index} />
</CardHeader>
<CardContent className="flex flex-wrap justify-between gap-x-10 gap-y-5">
<FeedFilter index={index} />
<TargetActionList index={index} />
</CardContent>
</Card>
)
}

const ActionCardToolbar = ({ index }: { index: number }) => {
const { t } = useTranslation("settings")

const name = useActionByIndex(index, (a) => a.name)
const disabled = useActionByIndex(index, (a) => a.result.disabled)

const onChange = actionActions.updateByIndex.bind(null, index)
return (
<div className="flex w-full items-center gap-2">
<Button
variant="ghost"
onClick={() => {
actionActions.removeByIndex(index)
}}
>
<i className="i-mgc-delete-2-cute-re text-zinc-600" />
</Button>
<p className="shrink-0 font-medium text-zinc-500">{t("actions.action_card.name")}</p>
<Input
value={name}
className="h-8 max-w-64"
onChange={(e) => {
onChange((data) => {
data.name = e.target.value
})
}}
/>
<div className="grow" />

<Switch
checked={!disabled}
onCheckedChange={(checked) => {
onChange((data) => {
data.result.disabled = !checked
})
}}
/>
</div>
)
}
75 changes: 75 additions & 0 deletions apps/renderer/src/modules/action/action-setting.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Button } from "@follow/components/ui/button/index.js"
import { LoadingWithIcon } from "@follow/components/ui/loading/index.jsx"
import { useMutation } from "@tanstack/react-query"
import { useTranslation } from "react-i18next"
import { toast } from "sonner"

import { toastFetchError } from "~/lib/error-parser"
import { queryClient } from "~/lib/query-client"
import { ActionCard } from "~/modules/action/action-card"
import { useActionsQuery } from "~/queries/actions"
import { actionActions, useActions, useIsActionDataDirty } from "~/store/action"

export const ActionSetting = () => {
const actionQuery = useActionsQuery()
const actionLength = useActions((actions) => actions.length)

if (actionQuery.isPending) {
return <LoadingWithIcon icon={<i className="i-mgc-magic-2-cute-re" />} size="large" />
}

return (
<div className="w-full max-w-4xl space-y-4">
{Array.from({ length: actionLength }).map((_action, actionIdx) => (
<ActionCard key={actionIdx} index={actionIdx} />
))}
<ActionSettingOperations />
</div>
)
}

function ActionSettingOperations() {
const { t } = useTranslation("settings")

const actionLength = useActions((actions) => actions.length)
const isDirty = useIsActionDataDirty()

const mutation = useMutation({
mutationFn: () => actionActions.updateRemoteActions(),
onSuccess: () => {
// apply new action settings
queryClient.invalidateQueries({
queryKey: ["entries"],
})
toast(t("actions.saveSuccess"))
},
onError: (error) => {
toastFetchError(error)
},
})

return (
<>
<Button
variant="outline"
className="center w-full gap-1"
onClick={() => {
actionActions.insertNewEmptyAction(t("actions.actionName", { number: actionLength + 1 }))
}}
>
<i className="i-mgc-add-cute-re" />
<span>{t("actions.newRule")}</span>
</Button>
<div className="text-right">
<Button
variant="primary"
disabled={!isDirty}
isLoading={mutation.isPending}
onClick={() => mutation.mutate()}
>
{t("actions.save")}
</Button>
</div>
</>
)
}
Loading

0 comments on commit 6d9212e

Please sign in to comment.