Skip to content

Commit 22f4020

Browse files
committed
fix: comment box
Signed-off-by: Innei <[email protected]>
1 parent 37be829 commit 22f4020

File tree

11 files changed

+104
-25
lines changed

11 files changed

+104
-25
lines changed

src/components/layout/footer/FooterInfo.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Link from 'next/link'
22

3+
import { SubscribeTextButton } from '~/components/widgets/subscribe/SubscribeTextButton'
34
import { kvKeys, redis } from '~/lib/redis.server'
45
import { isDev } from '~/utils/env'
56
import { clsxm } from '~/utils/helper'
@@ -121,6 +122,10 @@ const FooterBottom = async () => {
121122
<Divider />
122123
<a href="/sitemap.xml">站点地图</a>
123124
<Divider className="hidden md:inline" />
125+
126+
<SubscribeTextButton>
127+
<Divider className="hidden md:inline" />
128+
</SubscribeTextButton>
124129
</span>
125130
<span className="mt-3 block md:mt-0 md:inline">
126131
Stay hungry. Stay foolish.

src/components/layout/footer/GatewayCount.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const GatewayCount = () => {
99
as="span"
1010
TriggerComponent={GatewayCountTrigger}
1111
type="tooltip"
12+
wrapperClassName="cursor-help"
1213
>
1314
<div className="space-y-2 leading-relaxed">
1415
<p className="flex items-center space-x-1 opacity-80">

src/components/ui/dlalog/DialogOverlay.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as Dialog from '@radix-ui/react-dialog'
22
import { m } from 'framer-motion'
33

4-
export const DialogOverlay = () => {
4+
export const DialogOverlay = ({ onClick }: { onClick?: () => void }) => {
55
return (
66
<Dialog.Overlay asChild>
77
<m.div
8-
className="fixed inset-0 z-[11] bg-slate-50/80 backdrop-blur-sm dark:bg-neutral-900/80"
8+
onClick={onClick}
9+
className="fixed inset-0 z-[11] bg-slate-50/80 dark:bg-neutral-900/80"
910
initial={{ opacity: 0 }}
1011
animate={{ opacity: 1 }}
1112
exit={{ opacity: 0 }}

src/components/ui/form/FormInput.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AutoResizeHeight } from '~/components/widgets/shared/AutoResizeHeight'
99
import { jotaiStore } from '~/lib/store'
1010
import { clsxm } from '~/utils/helper'
1111

12+
import { Input } from '../input'
1213
import { useForm, useFormConfig } from './FormContext'
1314

1415
export const FormInput: FC<
@@ -68,13 +69,12 @@ export const FormInput: FC<
6869

6970
return (
7071
<>
71-
<input
72+
<Input
73+
// @ts-expect-error
7274
ref={inputRef}
7375
className={clsxm(
74-
'relative h-12 w-full rounded-lg bg-gray-200/50 px-3 dark:bg-zinc-800/50',
75-
'ring-accent/80 duration-200 focus:ring-2',
76-
'appearance-none',
7776
!!errorMessage && 'ring-2 ring-red-400 dark:ring-orange-700',
77+
'w-full',
7878
className,
7979
)}
8080
type="text"

src/components/ui/input/Input.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
import type { DetailedHTMLProps, FC, InputHTMLAttributes } from 'react'
1+
import { forwardRef } from 'react'
2+
import type { DetailedHTMLProps, InputHTMLAttributes } from 'react'
23

34
import { clsxm } from '~/utils/helper'
45

5-
export const Input: FC<
6-
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
7-
> = ({ className, ...props }) => {
6+
export const Input = forwardRef<
7+
HTMLInputElement,
8+
Omit<
9+
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,
10+
'ref'
11+
>
12+
>(({ className, ...props }, ref) => {
813
return (
914
<input
15+
ref={ref}
1016
className={clsxm(
1117
'min-w-0 flex-auto appearance-none rounded-lg border ring-accent/20 duration-200 sm:text-sm',
1218
'bg-base-100 px-3 py-[calc(theme(spacing.2)-1px)] placeholder:text-zinc-400 focus:outline-none focus:ring-2',
@@ -17,4 +23,5 @@ export const Input: FC<
1723
{...props}
1824
/>
1925
)
20-
}
26+
})
27+
Input.displayName = 'Input'

src/components/widgets/comment/CommentBox/CommentBoxLegacyForm.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const FormInput = (props: { fieldKey: FormKey; required?: boolean }) => {
3535
onChange={(e) => setValue(e.target.value)}
3636
required={required}
3737
placeholder={placeholderMap[key] + (required ? ' *' : '')}
38+
className="border-0 bg-gray-200/50 dark:bg-zinc-800/50"
3839
/>
3940
)
4041
}

src/components/widgets/subscribe/SubscribeModal.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { useEffect, useReducer } from 'react'
1+
import React, { useEffect, useReducer } from 'react'
22
import type { SubscribeTypeToBitMap } from '@mx-space/api-client'
33
import type { FC } from 'react'
44

55
import { StyledButton } from '~/components/ui/button'
66
import { Input } from '~/components/ui/input/Input'
77
import { useStateToRef } from '~/hooks/common/use-state-ref'
8+
import { preventDefault } from '~/lib/dom'
89
import { toast } from '~/lib/toast'
910
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'
1011
import { apiClient } from '~/utils/request'
@@ -82,7 +83,8 @@ export const SubscribeModal: FC<SubscribeModalProps> = ({
8283

8384
const query = useSubscribeStatusQuery()
8485

85-
const handleSubList = async () => {
86+
const handleSubList: React.EventHandler<any> = async (e) => {
87+
preventDefault(e)
8688
const { email, types } = state
8789
await apiClient.subscribe.subscribe(
8890
email,
@@ -97,7 +99,7 @@ export const SubscribeModal: FC<SubscribeModalProps> = ({
9799
const title = useAggregationSelector((data) => data.seo.title)
98100

99101
return (
100-
<form action="#" onSubmit={handleSubList} className="flex flex-col gap-5">
102+
<form onSubmit={handleSubList} className="flex flex-col gap-5">
101103
<p className="text-gray-1 text-sm">
102104
欢迎订阅「{title}
103105
」,我会定期推送最新的内容到你的邮箱。
@@ -111,16 +113,16 @@ export const SubscribeModal: FC<SubscribeModalProps> = ({
111113
dispatch({ type: 'set', data: { email: e.target.value } })
112114
}}
113115
/>
114-
<div className="flex gap-10">
116+
<div className="mb-2 flex gap-10">
115117
{Object.keys(state.types)
116118
.filter((type) => query.data?.allowTypes.includes(type as any))
117119
.map((name) => (
118120
<fieldset
119-
className="children:cursor-pointer inline-flex items-center text-lg"
121+
className="children:cursor-pointer inline-flex items-center text-sm"
120122
key={name}
121123
>
122124
<input
123-
className="checkbox-accent checkbox mr-2"
125+
className="checkbox-accent checkbox checkbox-sm mr-2"
124126
type="checkbox"
125127
onChange={(e) => {
126128
dispatch({
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use client'
2+
3+
import type { FC, PropsWithChildren } from 'react'
4+
5+
import { useIsEnableSubscribe, usePresentSubscribeModal } from './hooks'
6+
7+
export const SubscribeTextButton: FC<PropsWithChildren> = ({ children }) => {
8+
const canSubscribe = useIsEnableSubscribe()
9+
const { present } = usePresentSubscribeModal()
10+
11+
if (!canSubscribe) {
12+
return null
13+
}
14+
15+
return (
16+
<>
17+
<span>
18+
<button onClick={present}>订阅</button>
19+
</span>
20+
{children}
21+
</>
22+
)
23+
}

src/components/widgets/subscribe/hooks.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@ import { apiClient } from '~/utils/request'
66

77
import { SubscribeModal } from './SubscribeModal'
88

9-
const SWR_CHECK_SUBSCRIBE_KEY = ['subscribe-status']
9+
const QUERY_CHECK_SUBSCRIBE_KEY = ['subscribe-status']
1010

1111
export const useSubscribeStatusQuery = () => {
12-
return useQuery(SWR_CHECK_SUBSCRIBE_KEY, apiClient.subscribe.check, {
12+
return useQuery(QUERY_CHECK_SUBSCRIBE_KEY, apiClient.subscribe.check, {
1313
cacheTime: 60_000 * 10,
1414
})
1515
}
1616

1717
export const useIsEnableSubscribe = () =>
1818
useQuery({
19-
queryKey: SWR_CHECK_SUBSCRIBE_KEY,
19+
queryKey: QUERY_CHECK_SUBSCRIBE_KEY,
2020
queryFn: apiClient.subscribe.check,
2121
select: (data: { enable: boolean }) => data?.enable,
2222
cacheTime: 60_000 * 10,
2323
staleTime: 60_000 * 10,
24+
meta: {
25+
persist: false,
26+
},
2427
})
2528

2629
export const usePresentSubscribeModal = (

src/lib/dom.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { ReactEventHandler } from 'react'
2+
3+
export const stopPropagation: ReactEventHandler<any> = (e) =>
4+
e.stopPropagation()
5+
6+
export const preventDefault: ReactEventHandler<any> = (e) => e.preventDefault()

src/providers/root/modal-stack-provider.tsx

+35-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import * as Dialog from '@radix-ui/react-dialog'
2-
import { createElement, memo, useCallback, useId, useMemo, useRef } from 'react'
3-
import { AnimatePresence, m } from 'framer-motion'
2+
import {
3+
createElement,
4+
memo,
5+
useCallback,
6+
useEffect,
7+
useId,
8+
useMemo,
9+
useRef,
10+
} from 'react'
11+
import { AnimatePresence, m, useAnimationControls } from 'framer-motion'
412
import { atom, useAtomValue, useSetAtom } from 'jotai'
513
import type { Target, Transition } from 'framer-motion'
614
import type { FC, PropsWithChildren } from 'react'
@@ -10,6 +18,7 @@ import { Divider } from '~/components/ui/divider'
1018
import { DialogOverlay } from '~/components/ui/dlalog/DialogOverlay'
1119
import { microReboundPreset } from '~/constants/spring'
1220
import { useIsClient } from '~/hooks/common/use-is-client'
21+
import { stopPropagation } from '~/lib/dom'
1322
import { jotaiStore } from '~/lib/store'
1423
import { clsxm } from '~/utils/helper'
1524

@@ -118,26 +127,47 @@ export const Modal: Component<{
118127
},
119128
[close],
120129
)
130+
const animateController = useAnimationControls()
131+
useEffect(() => {
132+
animateController.start(enterStyle)
133+
}, [])
121134
return (
122135
<Dialog.Root open onOpenChange={onClose}>
123136
<Dialog.Portal>
124137
<DialogOverlay />
125138
<Dialog.Content asChild>
126-
<div className="fixed inset-0 z-[20] flex center">
139+
<div
140+
className="fixed inset-0 z-[20] flex center"
141+
onClick={() => {
142+
animateController
143+
.start({
144+
scale: 1.05,
145+
transition: {
146+
duration: 0.06,
147+
},
148+
})
149+
.then(() => {
150+
animateController.start({
151+
scale: 1,
152+
})
153+
})
154+
}}
155+
>
127156
<m.div
128157
style={useMemo(() => ({ zIndex: 99 + index }), [index])}
129158
exit={initialStyle}
130159
initial={initialStyle}
131-
animate={enterStyle}
160+
animate={animateController}
132161
transition={modalTransition}
133162
className={clsxm(
134163
'relative flex flex-col overflow-hidden rounded-lg',
135-
'bg-slate-50/90 dark:bg-neutral-900/90',
164+
'bg-slate-50/10 dark:bg-neutral-900/80',
136165
'p-2 shadow-2xl shadow-stone-300 backdrop-blur-sm dark:shadow-stone-800',
137166
'max-h-[70vh] min-w-[300px] max-w-[90vw] lg:max-h-[calc(100vh-20rem)] lg:max-w-[50vw]',
138167
'border border-slate-200 dark:border-neutral-800',
139168
item.modalClassName,
140169
)}
170+
onClick={stopPropagation}
141171
>
142172
<Dialog.Title className="flex-shrink-0 px-4 py-2 text-lg font-medium">
143173
{item.title}

0 commit comments

Comments
 (0)