Skip to content

Commit

Permalink
Showing 5 changed files with 278 additions and 136 deletions.
98 changes: 98 additions & 0 deletions apps/renderer/src/modules/rsshub/add-modal-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Button } from "@follow/components/ui/button/index.js"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@follow/components/ui/form/index.jsx"
import { Input } from "@follow/components/ui/input/Input.js"
import { zodResolver } from "@hookform/resolvers/zod"
import { useEffect } from "react"
import { useForm } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { z } from "zod"

import { whoami } from "~/atoms/user"
import { ShikiHighLighter } from "~/components/ui/code-highlighter"
import { useShikiDefaultTheme } from "~/components/ui/code-highlighter/shiki/hooks"
import { useAddRSSHubMutation } from "~/queries/rsshub"

export function AddModalContent({ dismiss }: { dismiss: () => void }) {
const { t } = useTranslation("settings")
const addRSSHubMutation = useAddRSSHubMutation()
const shikiTheme = useShikiDefaultTheme()
const me = whoami()

const formSchema = z.object({
baseUrl: z.string().url(),
accessKey: z.string().optional(),
})

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})

const onSubmit = (data: z.infer<typeof formSchema>) => {
addRSSHubMutation.mutate(data)
}

useEffect(() => {
if (addRSSHubMutation.isSuccess) {
dismiss()
}
}, [addRSSHubMutation.isSuccess])

return (
<div className="max-w-[550px] space-y-4 lg:min-w-[550px]">
<div className="text-sm">{t("rsshub.addModal.description")}</div>

<ShikiHighLighter
transparent
theme={shikiTheme}
className="group relative mt-3 cursor-auto select-text whitespace-pre break-words rounded-lg border border-border bg-zinc-100 p-2 text-sm dark:bg-neutral-800 [&_pre]:whitespace-pre [&_pre]:break-words [&_pre]:!p-0"
code={`FOLLOW_OWNER_USER_ID=${me?.handle || me?.id} # User id or handle of your follow account
FOLLOW_DESCRIPTION=${me?.name}'s instance # The description of your instance
FOLLOW_PRICE=0 # The monthly price of your instance, set to 0 means free.
FOLLOW_USER_LIMIT=1000 # The user limit of your instance, set it to 0 or 1 can make your instance private, leaving it empty means no restriction`}
language="dotenv"
/>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="baseUrl"
render={({ field }) => (
<FormItem>
<FormLabel>{t("rsshub.addModal.base_url_label")}</FormLabel>
<FormControl>
<Input placeholder="https://" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("rsshub.addModal.access_key_label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex items-center justify-end">
<Button type="submit" isLoading={addRSSHubMutation.isPending}>
{t("rsshub.addModal.add")}
</Button>
</div>
</form>
</Form>
</div>
)
}
148 changes: 148 additions & 0 deletions apps/renderer/src/modules/rsshub/set-modal-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { Button } from "@follow/components/ui/button/index.js"
import { Card, CardContent } from "@follow/components/ui/card/index.js"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@follow/components/ui/form/index.jsx"
import { Input } from "@follow/components/ui/input/Input.js"
import type { RSSHubModel } from "@follow/models"
import { zodResolver } from "@hookform/resolvers/zod"
import { useEffect } from "react"
import { useForm } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { z } from "zod"

import { whoami } from "~/atoms/user"
import { useAuthQuery } from "~/hooks/common"
import { UserAvatar } from "~/modules/user/UserAvatar"
import { Queries } from "~/queries"
import { useSetRSSHubMutation } from "~/queries/rsshub"

export function SetModalContent({
dismiss,
instance,
}: {
dismiss: () => void
instance: RSSHubModel
}) {
const { t } = useTranslation("settings")
const setRSSHubMutation = useSetRSSHubMutation()
const details = useAuthQuery(Queries.rsshub.get({ id: instance.id }))
const hasPurchase = !!details.data?.purchase
const price = instance.ownerUserId === whoami()?.id ? 0 : instance.price

const formSchema = z.object({
months: z.coerce
.number()
.min(hasPurchase ? 0 : 1)
.max(12),
})

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
months: hasPurchase ? 0 : 1,
},
})

const months = form.watch("months")

const onSubmit = (data: z.infer<typeof formSchema>) => {
setRSSHubMutation.mutate({ id: instance.id, durationInMonths: data.months })
}

useEffect(() => {
if (setRSSHubMutation.isSuccess) {
dismiss()
}
}, [setRSSHubMutation.isSuccess])

return (
<div className="max-w-[550px] space-y-4 lg:min-w-[550px]">
<Card>
<CardContent className="max-w-2xl space-y-2 p-6">
<div className="mb-3 text-lg font-medium">{t("rsshub.useModal.about")}</div>
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground">{t("rsshub.table.owner")}</div>
<UserAvatar
userId={instance.ownerUserId}
className="h-auto justify-start p-0"
avatarClassName="size-6"
/>
</div>
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground">{t("rsshub.table.description")}</div>
<div className="line-clamp-2">{instance.description}</div>
</div>
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground">{t("rsshub.table.price")}</div>
<div className="line-clamp-2 flex items-center gap-1">
{instance.price} <i className="i-mgc-power text-accent" />
</div>
</div>
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground">{t("rsshub.table.userCount")}</div>
<div className="line-clamp-2">{instance.userCount}</div>
</div>
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground">{t("rsshub.table.userLimit")}</div>
<div className="line-clamp-2">{instance.userLimit || t("rsshub.table.unlimited")}</div>
</div>
</CardContent>
</Card>
{details.data?.purchase && (
<div>
<div className="text-sm text-muted-foreground">
{t("rsshub.useModal.purchase_expires_at")}
</div>
<div className="line-clamp-2">
{new Date(details.data.purchase.expiresAt).toLocaleString()}
</div>
</div>
)}
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
{price > 0 && (
<FormField
control={form.control}
name="months"
render={({ field }) => (
<FormItem>
<FormLabel>{t("rsshub.useModal.months_label")}</FormLabel>
<FormControl>
<div className="flex items-center gap-10">
<div className="space-x-2">
<Input className="w-24" type="number" max={12} {...field} />
<span className="text-sm text-muted-foreground">
{t("rsshub.useModal.month")}
</span>
</div>
<div className="flex items-center gap-1">
{price * field.value}
<i className="i-mgc-power text-accent" />
</div>
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}
<div className="flex items-center justify-end">
<Button type="submit" isLoading={setRSSHubMutation.isPending}>
{price
? t("rsshub.useModal.useWith", {
amount: price * months,
})
: t("rsshub.table.use")}
</Button>
</div>
</form>
</Form>
</div>
)
}
Loading
Oops, something went wrong.

0 comments on commit 613b3b5

Please sign in to comment.