fix: fix sharing message use message action issue

This commit is contained in:
Zhang Minghan 2024-03-11 20:09:34 +08:00
parent a5d2c8c1ff
commit f7a135af0e
6 changed files with 51 additions and 38 deletions

View File

@ -41,6 +41,7 @@ type MessageProps = {
index: number; index: number;
message: Message; message: Message;
end?: boolean; end?: boolean;
username?: string;
onEvent?: (event: string, index?: number, message?: string) => void; onEvent?: (event: string, index?: number, message?: string) => void;
ref?: Ref<HTMLElement>; ref?: Ref<HTMLElement>;
sharing?: boolean; sharing?: boolean;
@ -216,10 +217,11 @@ function MessageContent({
index, index,
onEvent, onEvent,
selected, selected,
username,
}: MessageProps) { }: MessageProps) {
const isUser = message.role === "user"; const isUser = message.role === "user";
const username = useSelector(selectUsername); const user = useSelector(selectUsername);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [editedMessage, setEditedMessage] = useState<string | undefined>(""); const [editedMessage, setEditedMessage] = useState<string | undefined>("");
@ -239,7 +241,7 @@ function MessageContent({
isUser ? ( isUser ? (
<Avatar <Avatar
className={`message-avatar animate-fade-in`} className={`message-avatar animate-fade-in`}
username={username} username={username ?? user}
/> />
) : ( ) : (
<img <img

View File

@ -1,12 +0,0 @@
import { EventCommitter } from "./struct.ts";
import { Message } from "@/api/types.tsx";
export type SharingEvent = {
refer: string;
data: Message[];
};
export const sharingEvent = new EventCommitter<SharingEvent>({
name: "sharing",
destroyedAfterTrigger: true,
});

View File

@ -19,7 +19,6 @@ import MessageSegment from "@/components/Message.tsx";
import { Button } from "@/components/ui/button.tsx"; import { Button } from "@/components/ui/button.tsx";
import router from "@/router.tsx"; import router from "@/router.tsx";
import { useToast } from "@/components/ui/use-toast.ts"; import { useToast } from "@/components/ui/use-toast.ts";
import { sharingEvent } from "@/events/sharing.ts";
import { Message } from "@/api/types.tsx"; import { Message } from "@/api/types.tsx";
import Avatar from "@/components/Avatar.tsx"; import Avatar from "@/components/Avatar.tsx";
import { toJpeg } from "html-to-image"; import { toJpeg } from "html-to-image";
@ -28,18 +27,20 @@ import { extractMessage } from "@/utils/processor.ts";
import { cn } from "@/components/ui/lib/utils.ts"; import { cn } from "@/components/ui/lib/utils.ts";
import { useMobile } from "@/utils/device.ts"; import { useMobile } from "@/utils/device.ts";
import { ScrollArea } from "@/components/ui/scroll-area.tsx"; import { ScrollArea } from "@/components/ui/scroll-area.tsx";
import { useConversationActions } from "@/store/chat.ts";
type SharingFormProps = { type SharingFormProps = {
refer?: string; refer?: string;
data: ViewData | null; data: ViewData | null;
}; };
function SharingForm({ refer, data }: SharingFormProps) { function SharingForm({ data }: SharingFormProps) {
if (data === null) return null; if (data === null) return null;
const { t } = useTranslation(); const { t } = useTranslation();
const { toast } = useToast(); const { toast } = useToast();
const mobile = useMobile(); const mobile = useMobile();
const { mask: setMask } = useConversationActions();
const [maximized, setMaximized] = useState(false); const [maximized, setMaximized] = useState(false);
const container = useRef<HTMLDivElement>(null); const container = useRef<HTMLDivElement>(null);
const date = new Date(data.time); const date = new Date(data.time);
@ -111,7 +112,12 @@ function SharingForm({ refer, data }: SharingFormProps) {
</div> </div>
<div className={`shot-content`}> <div className={`shot-content`}>
{data.messages.map((message, i) => ( {data.messages.map((message, i) => (
<MessageSegment message={message} key={i} index={i} /> <MessageSegment
message={message}
key={i}
index={i}
username={data.username}
/>
))} ))}
</div> </div>
</div> </div>
@ -151,9 +157,11 @@ function SharingForm({ refer, data }: SharingFormProps) {
<Button <Button
variant={`outline`} variant={`outline`}
onClick={async () => { onClick={async () => {
sharingEvent.emit({ const message: Message[] = data?.messages || [];
refer: refer as string, setMask({
data: data?.messages as Message[], avatar: "",
name: data.name,
context: message,
}); });
await router.navigate("/"); await router.navigate("/");
}} }}

View File

@ -14,10 +14,10 @@ type Limiter struct {
Count int64 Count int64
} }
func (l *Limiter) RateLimit(client *redis.Client, ip string, path string) bool { func (l *Limiter) RateLimit(client *redis.Client, ip string, path string) (bool, error) {
key := fmt.Sprintf("rate:%s:%s", path, ip) key := fmt.Sprintf("rate:%s:%s", path, ip)
rate := utils.IncrWithLimit(client, key, 1, l.Count, int64(l.Duration)) rate, err := utils.IncrWithLimit(client, key, 1, l.Count, int64(l.Duration))
return !rate return !rate, err
} }
var limits = map[string]Limiter{ var limits = map[string]Limiter{
@ -64,7 +64,20 @@ func ThrottleMiddleware() gin.HandlerFunc {
cache := utils.GetCacheFromContext(c) cache := utils.GetCacheFromContext(c)
limiter := GetPrefixMap[Limiter](path, limits) limiter := GetPrefixMap[Limiter](path, limits)
if limiter != nil && limiter.RateLimit(cache, ip, path) { if limiter != nil {
rate, err := limiter.RateLimit(cache, ip, path)
if err != nil {
c.JSON(200, gin.H{
"status": false,
"reason": err.Error(),
"error": err.Error(),
})
c.Abort()
return
}
if rate {
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"status": false, "status": false,
"reason": "You have sent too many requests. Please try again later.", "reason": "You have sent too many requests. Please try again later.",
@ -73,6 +86,7 @@ func ThrottleMiddleware() gin.HandlerFunc {
c.Abort() c.Abort()
return return
} }
}
c.Next() c.Next()
} }
} }

View File

@ -53,25 +53,25 @@ func SetCache(cache *redis.Client, key string, value string, expiration int64) e
return cache.Set(context.Background(), key, value, time.Duration(expiration)*time.Second).Err() return cache.Set(context.Background(), key, value, time.Duration(expiration)*time.Second).Err()
} }
func IncrWithLimit(cache *redis.Client, key string, delta int64, limit int64, expiration int64) bool { func IncrWithLimit(cache *redis.Client, key string, delta int64, limit int64, expiration int64) (bool, error) {
// not exist // not exist
if _, err := cache.Get(context.Background(), key).Result(); err != nil { if _, err := cache.Get(context.Background(), key).Result(); err != nil {
if errors.Is(err, redis.Nil) { if errors.Is(err, redis.Nil) {
cache.Set(context.Background(), key, delta, time.Duration(expiration)*time.Second) cache.Set(context.Background(), key, delta, time.Duration(expiration)*time.Second)
return true return true, nil
} }
return false return false, err
} }
res, err := Incr(cache, key, delta) res, err := Incr(cache, key, delta)
if err != nil { if err != nil {
return false return false, err
} }
if res > limit { if res > limit {
// reset // reset
cache.Set(context.Background(), key, limit, time.Duration(expiration)*time.Second) cache.Set(context.Background(), key, limit, time.Duration(expiration)*time.Second)
return false return false, nil
} }
return true return true, nil
} }
func DecrInt(cache *redis.Client, key string, delta int64) bool { func DecrInt(cache *redis.Client, key string, delta int64) bool {

View File

@ -145,7 +145,8 @@ func (w *WebSocket) IncrRate(key string) bool {
func (w *WebSocket) IncrRateWithLimit(key string, limit int64, expiration int64) bool { func (w *WebSocket) IncrRateWithLimit(key string, limit int64, expiration int64) bool {
cache := w.GetCache() cache := w.GetCache()
return IncrWithLimit(cache, key, 1, limit, expiration) state, err := IncrWithLimit(cache, key, 1, limit, expiration)
return state && err == nil
} }
func (w *WebSocket) GetCtx() *gin.Context { func (w *WebSocket) GetCtx() *gin.Context {