wu981526092 commited on
Commit
8e42f9d
Β·
1 Parent(s): 1e144a5
frontend/src/components/shared/FloatingActionWidget.tsx CHANGED
@@ -34,10 +34,6 @@ import { useNavigation } from "@/context/NavigationContext";
34
  import { useTaskPolling } from "@/hooks/useTaskPolling";
35
  import { api } from "@/lib/api";
36
 
37
- // Disable jittery animations/motion for the floating widget in HF build
38
- const DISABLE_FLOATING_WIDGET_JITTER = true;
39
- const FLOATING_WIDGET_MINIMAL = true; // fixed bottom-right, no drag/tooltip; click opens splitter
40
-
41
  // Add custom glow animation styles
42
  const glowStyle = `
43
  @keyframes magical-glow {
@@ -143,7 +139,7 @@ export function FloatingActionWidget() {
143
 
144
  const [isExpanded, setIsExpanded] = useState(false);
145
  const [isDragging, setIsDragging] = useState(false);
146
- const [showTooltip, setShowTooltip] = useState(!FLOATING_WIDGET_MINIMAL);
147
  const [hasMoved, setHasMoved] = useState(false);
148
  const [currentMood, setCurrentMood] = useState<PetMood>("curious");
149
  const [currentMessage, setCurrentMessage] = useState<PetMessage>({
@@ -328,10 +324,10 @@ export function FloatingActionWidget() {
328
  // Hide tooltip after 6 seconds or when expanded
329
  useEffect(() => {
330
  const timer = setTimeout(() => {
331
- if (!FLOATING_WIDGET_MINIMAL) setShowTooltip(false);
332
  }, 6000);
333
 
334
- if (isExpanded && !FLOATING_WIDGET_MINIMAL) {
335
  setShowTooltip(false);
336
  }
337
 
@@ -443,22 +439,62 @@ export function FloatingActionWidget() {
443
  };
444
  }, [lastInteraction]);
445
 
446
- // Random movement behavior (disabled to prevent jitter)
447
  useEffect(() => {
448
- if (DISABLE_FLOATING_WIDGET_JITTER) return;
449
  if (isDragging || isExpanded) return;
450
 
451
  const randomMove = () => {
452
- /* disabled */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  };
454
 
455
- const moveInterval = setInterval(randomMove, 60000);
 
456
  return () => clearInterval(moveInterval);
457
  }, [isDragging, isExpanded]);
458
 
459
  // Handle mouse down for dragging
460
  const handleMouseDown = (e: React.MouseEvent) => {
461
- if (FLOATING_WIDGET_MINIMAL) return; // disable drag in minimal mode
462
  if (!widgetRef.current) return;
463
 
464
  e.preventDefault();
@@ -541,12 +577,6 @@ export function FloatingActionWidget() {
541
  // Prevent toggle during dragging or if widget was just moved
542
  if (isDragging || hasMoved) return;
543
 
544
- if (FLOATING_WIDGET_MINIMAL) {
545
- setIsSplitterModalOpen(true);
546
- setLastInteraction(Date.now());
547
- return;
548
- }
549
-
550
  setIsExpanded(!isExpanded);
551
  setLastInteraction(Date.now()); // Update interaction time
552
  };
@@ -830,11 +860,12 @@ export function FloatingActionWidget() {
830
  {/* Collapsed Widget */}
831
  <div
832
  ref={widgetRef}
833
- className={`fixed ${FLOATING_WIDGET_MINIMAL ? "cursor-pointer" : isDragging ? "cursor-grabbing select-none" : "cursor-grab"}`}
 
 
834
  style={{
835
- ...(FLOATING_WIDGET_MINIMAL
836
- ? { right: 20, bottom: 20 }
837
- : { left: `${position.x}px`, top: `${position.y}px` }),
838
  zIndex: 9999,
839
  pointerEvents: "auto",
840
  transition: isDragging ? "none" : "all 0.1s ease",
@@ -843,24 +874,23 @@ export function FloatingActionWidget() {
843
  {/* Pet Widget - Always visible */}
844
  <div className="relative">
845
  <div
846
- className={`w-14 h-14 bg-primary hover:bg-primary/90 rounded-full shadow-lg flex flex-col items-center justify-center cursor-pointer transition-all duration-200 ${
847
- FLOATING_WIDGET_MINIMAL ? "" : "hover:scale-110"
848
- } relative ${
849
- showTooltip && !FLOATING_WIDGET_MINIMAL ? "shadow-primary/50 shadow-2xl" : ""
850
- } ${isDragging && !FLOATING_WIDGET_MINIMAL ? "scale-110 shadow-2xl opacity-90" : ""} ${
851
- isExpanded && !FLOATING_WIDGET_MINIMAL ? "ring-2 ring-primary/50 ring-offset-2" : ""
852
- } ${
853
- isAtChartCenter && !FLOATING_WIDGET_MINIMAL
854
  ? "ring-4 ring-blue-400/50 ring-offset-4 shadow-xl shadow-blue-500/30 scale-110"
855
  : ""
856
  }`}
857
  onMouseDown={handleMouseDown}
858
- onMouseEnter={FLOATING_WIDGET_MINIMAL ? undefined : handleMouseEnter}
859
- onMouseLeave={FLOATING_WIDGET_MINIMAL ? undefined : handleMouseLeave}
860
  onClick={toggleExpanded}
861
  style={{
862
- // Disable glow animation to avoid jitter
863
- animation: undefined,
 
864
  transition: isDragging ? "none" : "all 0.2s ease",
865
  transform: `scale(${petScale})`,
866
  }}
@@ -873,8 +903,8 @@ export function FloatingActionWidget() {
873
  </div>
874
 
875
  {/* Pet tooltip with mood-based messages - only show when collapsed */}
876
- {showTooltip && !isExpanded && !FLOATING_WIDGET_MINIMAL && (
877
- <div className="absolute -top-16 -right-4 w-48 bg-black/90 text-white text-xs px-3 py-2 rounded-lg shadow-lg z-10">
878
  <div className="text-center">{currentMessage.text}</div>
879
  <div className="absolute top-full right-6 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-black/90"></div>
880
  </div>
@@ -883,7 +913,7 @@ export function FloatingActionWidget() {
883
  </div>
884
 
885
  {/* Expanded Panel - Positioned Separately */}
886
- {isExpanded && !FLOATING_WIDGET_MINIMAL && (
887
  <div
888
  className="fixed"
889
  style={{
 
34
  import { useTaskPolling } from "@/hooks/useTaskPolling";
35
  import { api } from "@/lib/api";
36
 
 
 
 
 
37
  // Add custom glow animation styles
38
  const glowStyle = `
39
  @keyframes magical-glow {
 
139
 
140
  const [isExpanded, setIsExpanded] = useState(false);
141
  const [isDragging, setIsDragging] = useState(false);
142
+ const [showTooltip, setShowTooltip] = useState(true);
143
  const [hasMoved, setHasMoved] = useState(false);
144
  const [currentMood, setCurrentMood] = useState<PetMood>("curious");
145
  const [currentMessage, setCurrentMessage] = useState<PetMessage>({
 
324
  // Hide tooltip after 6 seconds or when expanded
325
  useEffect(() => {
326
  const timer = setTimeout(() => {
327
+ setShowTooltip(false);
328
  }, 6000);
329
 
330
+ if (isExpanded) {
331
  setShowTooltip(false);
332
  }
333
 
 
439
  };
440
  }, [lastInteraction]);
441
 
442
+ // Random movement behavior (when not being dragged)
443
  useEffect(() => {
 
444
  if (isDragging || isExpanded) return;
445
 
446
  const randomMove = () => {
447
+ const moveChance = Math.random();
448
+ if (moveChance < 0.2) {
449
+ // 20% chance to move
450
+ const margin = 100;
451
+ const newX =
452
+ margin + Math.random() * (window.innerWidth - 300 - margin);
453
+ const newY =
454
+ margin + Math.random() * (window.innerHeight - 200 - margin);
455
+
456
+ setPosition({ x: newX, y: newY });
457
+ setIsAnimating(true);
458
+
459
+ // Show a playful message during movement
460
+ const playfulMessages = [
461
+ {
462
+ text: "πŸƒβ€β™‚οΈ Just stretching my legs!",
463
+ mood: "excited" as PetMood,
464
+ emoji: "πŸƒβ€β™‚οΈ",
465
+ },
466
+ {
467
+ text: "πŸ”„ Change of scenery!",
468
+ mood: "happy" as PetMood,
469
+ emoji: "πŸ”„",
470
+ },
471
+ {
472
+ text: "πŸ‘€ Exploring your workspace!",
473
+ mood: "curious" as PetMood,
474
+ emoji: "πŸ‘€",
475
+ },
476
+ ];
477
+ const randomMsg =
478
+ playfulMessages[Math.floor(Math.random() * playfulMessages.length)];
479
+ if (!randomMsg) return;
480
+ setCurrentMessage(randomMsg);
481
+ setCurrentMood(randomMsg.mood);
482
+ setShowTooltip(true);
483
+
484
+ setTimeout(() => {
485
+ setIsAnimating(false);
486
+ setShowTooltip(false);
487
+ }, 2000);
488
+ }
489
  };
490
 
491
+ // Check for random movement every 30-60 seconds
492
+ const moveInterval = setInterval(randomMove, 45000);
493
  return () => clearInterval(moveInterval);
494
  }, [isDragging, isExpanded]);
495
 
496
  // Handle mouse down for dragging
497
  const handleMouseDown = (e: React.MouseEvent) => {
 
498
  if (!widgetRef.current) return;
499
 
500
  e.preventDefault();
 
577
  // Prevent toggle during dragging or if widget was just moved
578
  if (isDragging || hasMoved) return;
579
 
 
 
 
 
 
 
580
  setIsExpanded(!isExpanded);
581
  setLastInteraction(Date.now()); // Update interaction time
582
  };
 
860
  {/* Collapsed Widget */}
861
  <div
862
  ref={widgetRef}
863
+ className={`fixed ${
864
+ isDragging ? "cursor-grabbing select-none" : "cursor-grab"
865
+ }`}
866
  style={{
867
+ left: `${position.x}px`,
868
+ top: `${position.y}px`,
 
869
  zIndex: 9999,
870
  pointerEvents: "auto",
871
  transition: isDragging ? "none" : "all 0.1s ease",
 
874
  {/* Pet Widget - Always visible */}
875
  <div className="relative">
876
  <div
877
+ className={`w-14 h-14 bg-primary hover:bg-primary/90 rounded-full shadow-lg flex flex-col items-center justify-center cursor-pointer transition-all duration-200 hover:scale-110 relative ${
878
+ showTooltip ? "shadow-primary/50 shadow-2xl" : ""
879
+ } ${isDragging ? "scale-110 shadow-2xl opacity-90" : ""} ${
880
+ isAnimating ? "animate-pulse" : ""
881
+ } ${isExpanded ? "ring-2 ring-primary/50 ring-offset-2" : ""} ${
882
+ isAtChartCenter
 
 
883
  ? "ring-4 ring-blue-400/50 ring-offset-4 shadow-xl shadow-blue-500/30 scale-110"
884
  : ""
885
  }`}
886
  onMouseDown={handleMouseDown}
887
+ onMouseEnter={handleMouseEnter}
888
+ onMouseLeave={handleMouseLeave}
889
  onClick={toggleExpanded}
890
  style={{
891
+ animation: showTooltip
892
+ ? "magical-glow 2s ease-in-out infinite"
893
+ : undefined,
894
  transition: isDragging ? "none" : "all 0.2s ease",
895
  transform: `scale(${petScale})`,
896
  }}
 
903
  </div>
904
 
905
  {/* Pet tooltip with mood-based messages - only show when collapsed */}
906
+ {showTooltip && !isExpanded && (
907
+ <div className="absolute -top-16 -right-4 w-48 bg-black/90 text-white text-xs px-3 py-2 rounded-lg shadow-lg animate-bounce z-10">
908
  <div className="text-center">{currentMessage.text}</div>
909
  <div className="absolute top-full right-6 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-black/90"></div>
910
  </div>
 
913
  </div>
914
 
915
  {/* Expanded Panel - Positioned Separately */}
916
+ {isExpanded && (
917
  <div
918
  className="fixed"
919
  style={{