θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
} from "@phosphor-icons/react";
import { useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import { Tooltip } from "react-tooltip";
import { createPortal } from "react-dom";

const THREAD_CALLOUT_DETAIL_WIDTH = 26;
export default function ThreadItem({
Expand All @@ -31,123 +33,140 @@ export default function ThreadItem({
: paths.workspace.thread(slug, thread.slug);

return (
<div
className="w-full relative flex h-[38px] items-center border-none rounded-lg"
role="listitem"
>
{/* Curved line Element and leader if required */}
<>
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
className={`${
isActive
? "border-l-2 border-b-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-b border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[50%] absolute top-0 left-3 rounded-bl-lg`}
></div>
{/* Downstroke border for next item */}
{hasNext && (
className="w-full relative flex h-[38px] items-center border-none rounded-lg"
role="listitem"
>
{/* Curved line Element and leader if required */}
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
className={`${
idx <= activeIdx && !isActive
? "border-l-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[100%] absolute top-0 left-3`}
isActive
? "border-l-2 border-b-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-b border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[50%] absolute top-0 left-3 rounded-bl-lg`}
></div>
)}
{/* Downstroke border for next item */}
{hasNext && (
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
className={`${
idx <= activeIdx && !isActive
? "border-l-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[100%] absolute top-0 left-3`}
></div>
)}

{/* Curved line inline placeholder for spacing - not visible */}
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH + 8 }}
className="h-full"
/>
<div
className={`flex w-full items-center justify-between pr-2 group relative ${isActive ? "bg-[var(--theme-sidebar-thread-selected)] border border-solid border-transparent light:border-blue-400" : "hover:bg-theme-sidebar-subitem-hover"} rounded-[4px]`}
>
{thread.deleted ? (
<div className="w-full flex justify-between">
<div className="w-full pl-2 py-1">
<p
className={`text-left text-sm text-slate-400/50 light:text-slate-500 italic`}
>
deleted thread
</p>
{/* Curved line inline placeholder for spacing - not visible */}
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH + 8 }}
className="h-full"
/>
<div
className={`flex w-full items-center justify-between pr-2 group relative ${isActive ? "bg-[var(--theme-sidebar-thread-selected)] border border-solid border-transparent light:border-blue-400" : "hover:bg-theme-sidebar-subitem-hover"} rounded-[4px]`}
>
{thread.deleted ? (
<div className="w-full flex justify-between">
<div className="w-full pl-2 py-1">
<p
className={`text-left text-sm text-slate-400/50 light:text-slate-500 italic`}
>
deleted thread
</p>
</div>
{ctrlPressed && (
<button
type="button"
className="border-none"
onClick={() => toggleMarkForDeletion(thread.id)}
>
<ArrowCounterClockwise
className="text-zinc-300 hover:text-white light:text-theme-text-secondary hover:light:text-theme-text-primary"
size={18}
/>
</button>
)}
</div>
{ctrlPressed && (
<button
type="button"
className="border-none"
onClick={() => toggleMarkForDeletion(thread.id)}
>
<ArrowCounterClockwise
className="text-zinc-300 hover:text-white light:text-theme-text-secondary hover:light:text-theme-text-primary"
size={18}
/>
</button>
)}
</div>
) : (
<a
href={
window.location.pathname === linkTo || ctrlPressed ? "#" : linkTo
}
className="w-full pl-2 py-1 overflow-hidden"
aria-current={isActive ? "page" : ""}
>
<p
className={`text-left text-sm truncate max-w-[150px] ${
isActive ? "font-medium text-white" : "text-theme-text-primary"
}`}
) : (
<a
href={
window.location.pathname === linkTo || ctrlPressed
? "#"
: linkTo
}
className="w-full pl-2 py-1 overflow-hidden"
aria-current={isActive ? "page" : ""}
>
{thread.name}
</p>
</a>
)}
{!!thread.slug && !thread.deleted && (
<div ref={optionsContainer} className="flex items-center">
{" "}
{/* Added flex and items-center */}
{ctrlPressed ? (
<button
type="button"
className="border-none"
onClick={() => toggleMarkForDeletion(thread.id)}
<p
data-tooltip-id="thread-name"
data-tooltip-content={thread.name}
className={`text-left text-sm truncate max-w-[150px] ${
isActive
? "font-medium text-white"
: "text-theme-text-primary"
}`}
>
<X
className="text-zinc-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
weight="bold"
size={18}
/>
</button>
) : (
<div className="flex items-center w-fit group-hover:visible md:invisible gap-x-1">
{thread.name}
</p>
</a>
)}
{!!thread.slug && !thread.deleted && (
<div ref={optionsContainer} className="flex items-center">
{" "}
{/* Added flex and items-center */}
{ctrlPressed ? (
<button
type="button"
className="border-none"
onClick={() => setShowOptions(!showOptions)}
aria-label="Thread options"
onClick={() => toggleMarkForDeletion(thread.id)}
>
<DotsThree
className="text-slate-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
size={25}
<X
className="text-zinc-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
weight="bold"
size={18}
/>
</button>
</div>
)}
{showOptions && (
<OptionsMenu
containerRef={optionsContainer}
workspace={workspace}
thread={thread}
onRemove={onRemove}
close={() => setShowOptions(false)}
currentThreadSlug={threadSlug}
/>
)}
</div>
)}
) : (
<div className="flex items-center w-fit group-hover:visible md:invisible gap-x-1">
<button
type="button"
className="border-none"
onClick={() => setShowOptions(!showOptions)}
aria-label="Thread options"
>
<DotsThree
className="text-slate-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
size={25}
/>
</button>
</div>
)}
{showOptions && (
<OptionsMenu
containerRef={optionsContainer}
workspace={workspace}
thread={thread}
onRemove={onRemove}
close={() => setShowOptions(false)}
currentThreadSlug={threadSlug}
/>
)}
</div>
)}
</div>
</div>
</div>
{createPortal(
<Tooltip
id="thread-name"
place="right"
delayShow={300}
className="tooltip !text-xs z-99"
/>,
document.body
)}
</>
);
}

Expand Down
13 changes: 13 additions & 0 deletions frontend/src/components/Sidebar/ActiveWorkspaces/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import ThreadContainer from "./ThreadContainer";
import { useMatch } from "react-router-dom";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import showToast from "@/utils/toast";
import { Tooltip } from "react-tooltip";
import { createPortal } from "react-dom";

export default function ActiveWorkspaces() {
const navigate = useNavigate();
Expand Down Expand Up @@ -129,6 +131,8 @@ export default function ActiveWorkspaces() {
<div className="flex items-center space-x-2 overflow-hidden flex-grow">
<div className="w-[130px] overflow-hidden">
<p
data-tooltip-id="workspace-name"
data-tooltip-content={workspace.name}
className={`
text-[14px] leading-loose whitespace-nowrap overflow-hidden text-white
${isActive ? "font-bold" : "font-medium"} truncate
Expand Down Expand Up @@ -205,6 +209,15 @@ export default function ActiveWorkspaces() {
</div>
)}
</Droppable>
{createPortal(
<Tooltip
id="workspace-name"
place="right"
delayShow={300}
className="tooltip !text-xs z-99"
/>,
document.body
)}
</DragDropContext>
);
}