refactor(mascot): simplify chat visibility logic and add persistent chat mode
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { BarChart3, MessageSquare, Radio } from "lucide-react";
|
import { BarChart3, MessageSquare, Radio } from "lucide-react";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import type { DashboardTab } from "../entities/ui/types";
|
import type { DashboardTab } from "../entities/ui/types";
|
||||||
import type { MessageRecord } from "../shared/api/client";
|
import type { MessageRecord } from "../shared/api/client";
|
||||||
import { useMascotChat } from "../shared/hooks/useMascotChat";
|
import { useMascotChat } from "../shared/hooks/useMascotChat";
|
||||||
@@ -34,7 +33,6 @@ export function Sidebar({
|
|||||||
guildId,
|
guildId,
|
||||||
channelId,
|
channelId,
|
||||||
}: SidebarProps) {
|
}: SidebarProps) {
|
||||||
const [showChat, setShowChat] = useState(false);
|
|
||||||
const mascotChat = useMascotChat({
|
const mascotChat = useMascotChat({
|
||||||
messageCount: recentMessages.length,
|
messageCount: recentMessages.length,
|
||||||
activeParticipants: new Set(recentMessages.map((message) => message.user_id)).size,
|
activeParticipants: new Set(recentMessages.map((message) => message.user_id)).size,
|
||||||
@@ -43,12 +41,6 @@ export function Sidebar({
|
|||||||
guildId,
|
guildId,
|
||||||
channelId,
|
channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (mascotChatMessage) {
|
|
||||||
setShowChat(true);
|
|
||||||
}
|
|
||||||
}, [mascotChatMessage]);
|
|
||||||
return (
|
return (
|
||||||
<motion.nav
|
<motion.nav
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -121,8 +113,12 @@ export function Sidebar({
|
|||||||
>
|
>
|
||||||
<MascotImage
|
<MascotImage
|
||||||
size="sm"
|
size="sm"
|
||||||
showChat={showChat && !mascotChat.isOpen}
|
showChat={!mascotChat.isOpen}
|
||||||
chatMessage={mascotChatMessage}
|
chatMessage={
|
||||||
|
mascotChatMessage ||
|
||||||
|
"Halo! Saya mascot mu. Klik aku kalau mau tanya soal obrolan atau moderasi ✨"
|
||||||
|
}
|
||||||
|
persistChat
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<MascotChatbot
|
<MascotChatbot
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface MascotImageProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
showChat?: boolean;
|
showChat?: boolean;
|
||||||
chatMessage?: string;
|
chatMessage?: string;
|
||||||
|
persistChat?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sizeMap = {
|
const sizeMap = {
|
||||||
@@ -32,6 +33,7 @@ export function MascotImage({
|
|||||||
className = "",
|
className = "",
|
||||||
showChat = false,
|
showChat = false,
|
||||||
chatMessage = "",
|
chatMessage = "",
|
||||||
|
persistChat = false,
|
||||||
}: MascotImageProps) {
|
}: MascotImageProps) {
|
||||||
const sizeClass = sizeMap[size];
|
const sizeClass = sizeMap[size];
|
||||||
const chatSizeClass = chatSizeMap[size];
|
const chatSizeClass = chatSizeMap[size];
|
||||||
@@ -40,10 +42,12 @@ export function MascotImage({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showChat && chatMessage) {
|
if (showChat && chatMessage) {
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
if (persistChat) return;
|
||||||
const timer = setTimeout(() => setIsVisible(false), 8000); // Auto hide after 8s
|
const timer = setTimeout(() => setIsVisible(false), 8000); // Auto hide after 8s
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}
|
}
|
||||||
}, [showChat, chatMessage]);
|
setIsVisible(false);
|
||||||
|
}, [showChat, chatMessage, persistChat]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative inline-block">
|
<div className="relative inline-block">
|
||||||
|
|||||||
Reference in New Issue
Block a user