Skip to content

Commit

Permalink
Merge pull request #51 from Gurubase/develop
Browse files Browse the repository at this point in the history
Fix binge map upon entering a binge
  • Loading branch information
fatihbaltaci authored Jan 22, 2025
2 parents a2fce02 + 2763ad9 commit 3b7c436
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 440 deletions.
63 changes: 63 additions & 0 deletions src/gurubase-frontend/src/components/BingeMap/BingeMapGraph.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import BingeMapNode from './BingeMapNode';

const BingeMapGraph = ({
links,
nodes,
nodeSize,
pan,
scale,
isDragging,
getNodeColor,
areNodesDisabled,
handleNodeClick,
handleNodeHover
}) => {
return (
<div className="w-full h-full overflow-hidden flex-1 min-h-0">
<svg
width="1000"
height="1000"
className="w-full h-full overflow-visible bg-transparent"
style={{
transform: `translate(${pan.x}px, ${pan.y}px) scale(${scale})`,
transition: isDragging ? "none" : "transform 0.3s ease-out",
transformOrigin: "0 0"
}}>
<g>
{/* Draw connection lines */}
{links.map((link) => (
<line
key={link.id}
x1={link.x1}
y1={link.y1}
x2={link.x2}
y2={link.y2}
stroke="hsl(var(--muted-foreground))"
strokeWidth={Math.max(1, nodeSize / 12)}
opacity={link.id.includes("streaming-temp") ? "0.3" : "0.5"}
strokeDasharray={
link.id.includes("streaming-temp") ? "5,5" : "none"
}
/>
))}

{/* Draw nodes */}
{nodes.map((node) => (
<BingeMapNode
key={node.id}
node={node}
nodeSize={nodeSize}
getNodeColor={getNodeColor}
areNodesDisabled={areNodesDisabled}
handleNodeClick={handleNodeClick}
handleNodeHover={handleNodeHover}
/>
))}
</g>
</svg>
</div>
);
};

export default BingeMapGraph;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import { Button } from "@/components/ui/button";
import Image from "next/image";
import MapArrowUp from "@/assets/images/map-arrow-up.svg";
import clsx from "clsx";

const BingeMapMobileButton = ({
activeNode,
nodes,
streamingStatus,
handleNodeSelect
}) => {
return (
<div
className="fixed left-1/2 transform -translate-x-1/2 md:hidden"
style={{
bottom: "calc(6vh + 24px)"
}}>
<Button
className={clsx(
"w-[90px] rounded-full text-white flex items-center justify-center",
activeNode
? "bg-zinc-900 hover:bg-zinc-800 cursor-pointer"
: "bg-zinc-500 hover:bg-zinc-500 cursor-not-allowed"
)}
onClick={() => {
if (activeNode) {
const selectedNode = nodes.find(
(node) => node.id === activeNode
);
if (selectedNode?.slug) {
handleNodeSelect(selectedNode);
}
}
}}
disabled={!activeNode || streamingStatus}>
<Image
src={MapArrowUp}
alt="Map Arrow Up"
width={13}
height={13}
className="mr-2"
/>
<span>Open</span>
</Button>
</div>
);
};

export default BingeMapMobileButton;
43 changes: 43 additions & 0 deletions src/gurubase-frontend/src/components/BingeMap/BingeMapNode.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';

const BingeMapNode = ({
node,
nodeSize,
getNodeColor,
areNodesDisabled,
handleNodeClick,
handleNodeHover
}) => {
return (
<g key={node.id}>
<circle
cx={node.x}
cy={node.y}
r={nodeSize}
fill={getNodeColor(node)}
className={`transition-colors duration-200 ${
areNodesDisabled()
? "cursor-not-allowed"
: "cursor-pointer"
}`}
onClick={() => {
if (!areNodesDisabled()) {
handleNodeClick(node.id);
}
}}
onMouseEnter={() => {
if (!areNodesDisabled()) {
handleNodeHover(node.id);
}
}}
onMouseLeave={() => {
if (!areNodesDisabled()) {
handleNodeHover(null);
}
}}
/>
</g>
);
};

export default BingeMapNode;
53 changes: 53 additions & 0 deletions src/gurubase-frontend/src/components/BingeMap/BingeMapTooltip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';

const BingeMapTooltip = ({ node, scale, pan, nodes }) => {
if (!node) return null;

const nodeY = node.y * scale + pan.y;
const nodeX = node.x * scale + pan.x;

const isRootNode = !nodes.some((n) =>
n.children?.some((child) => child.id === node.id)
);

const tooltipOnBottom = !isRootNode;

return (
<div
className="absolute rounded-lg shadow-lg p-3 border md:bg-[#1B242D] md:text-white bg-background"
style={{
left: `${nodeX}px`,
top: `${nodeY + (tooltipOnBottom ? -24 : 24)}px`,
transform: `translate(-50%, ${tooltipOnBottom ? "-100%" : "0"}) scale(${scale})`,
maxWidth: "300px",
minWidth: "100px",
width: "max-content",
transformOrigin: tooltipOnBottom
? "bottom center"
: "top center",
zIndex: 50
}}>
{/* Triangle pointer */}
<div
className="absolute w-4 h-4 border-l border-t md:bg-[#1B242D] bg-background"
style={{
[tooltipOnBottom ? "bottom" : "top"]: "-8px",
left: "50%",
transform: `translateX(-50%) rotate(${tooltipOnBottom ? "225deg" : "45deg"})`,
borderColor: "inherit"
}}
/>
<p
className="text-center relative font-inter px-2"
style={{
fontSize: "12px",
fontWeight: 500,
lineHeight: "normal"
}}>
{node.text}
</p>
</div>
);
};

export default BingeMapTooltip;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';

const BingeMapZoomControls = ({ scale, handleZoomIn, handleZoomOut, MIN_SCALE, MAX_SCALE }) => {
return (
<div className="absolute top-2 right-3 flex flex-col gap-2 z-[51]">
<button
onClick={handleZoomIn}
className="p-2 bg-white rounded-full shadow-lg hover:bg-gray-50 transition-colors cursor-pointer"
disabled={scale >= MAX_SCALE}
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
>
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
<line x1="11" y1="8" x2="11" y2="14" />
<line x1="8" y1="11" x2="14" y2="11" />
</svg>
</button>
<button
onClick={handleZoomOut}
className="p-2 bg-white rounded-full shadow-lg hover:bg-gray-50 transition-colors cursor-pointer"
disabled={scale <= MIN_SCALE}
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
>
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
<line x1="8" y1="11" x2="14" y2="11" />
</svg>
</button>
</div>
);
};

export default BingeMapZoomControls;
Loading

0 comments on commit 3b7c436

Please sign in to comment.