fix(app): reveal tab avatar on hover (#33824)
Co-authored-by: Test <test@opencode.test>
This commit is contained in:
co-authored by
Test
parent
b44af11e03
commit
5471d2a769
@@ -27,7 +27,17 @@ export function SessionTabAvatar(props: {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SessionProgressIndicatorV2 class="shrink-0" />
|
<span class="relative block size-4 shrink-0">
|
||||||
|
<SessionProgressIndicatorV2 class="absolute inset-0 group-hover:invisible" />
|
||||||
|
<span class="invisible absolute inset-0 group-hover:visible">
|
||||||
|
<ProjectAvatar
|
||||||
|
fallback={displayName(props.project ?? { worktree: props.directory })}
|
||||||
|
src={getProjectAvatarSource(props.project?.id, props.project?.icon)}
|
||||||
|
variant={getProjectAvatarVariant(props.project?.icon?.color)}
|
||||||
|
unread={state.unread()}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
|
|||||||
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
||||||
import { Dialog } from "@opencode-ai/ui/dialog"
|
import { Dialog } from "@opencode-ai/ui/dialog"
|
||||||
import { InlineInput } from "@opencode-ai/ui/inline-input"
|
import { InlineInput } from "@opencode-ai/ui/inline-input"
|
||||||
import { Spinner } from "@opencode-ai/ui/spinner"
|
|
||||||
import { SessionRetry } from "@opencode-ai/session-ui/session-retry"
|
import { SessionRetry } from "@opencode-ai/session-ui/session-retry"
|
||||||
import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
||||||
import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
|
import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
|
||||||
@@ -66,9 +65,7 @@ import { legacySessionHref, requireServerKey, sessionHref } from "@/utils/sessio
|
|||||||
import { useSDK } from "@/context/sdk"
|
import { useSDK } from "@/context/sdk"
|
||||||
import { useSync } from "@/context/sync"
|
import { useSync } from "@/context/sync"
|
||||||
import { notifySessionTabsRemoved } from "@/components/titlebar-session-events"
|
import { notifySessionTabsRemoved } from "@/components/titlebar-session-events"
|
||||||
import { messageAgentColor } from "@/utils/agent"
|
|
||||||
import { sessionTitle } from "@/utils/session-title"
|
import { sessionTitle } from "@/utils/session-title"
|
||||||
import { makeTimer } from "@solid-primitives/timer"
|
|
||||||
import { scheduleConnectedMeasure } from "./measure"
|
import { scheduleConnectedMeasure } from "./measure"
|
||||||
import { createTimelineProjection } from "./projection"
|
import { createTimelineProjection } from "./projection"
|
||||||
import { MessageComment, SummaryDiff, TimelineRow, TimelineRowMap } from "./rows"
|
import { MessageComment, SummaryDiff, TimelineRow, TimelineRowMap } from "./rows"
|
||||||
@@ -277,25 +274,7 @@ export function MessageTimeline(props: {
|
|||||||
if (!id) return idle
|
if (!id) return idle
|
||||||
return sync().data.session_status[id] ?? idle
|
return sync().data.session_status[id] ?? idle
|
||||||
})
|
})
|
||||||
const working = createMemo(() => sessionStatus().type !== "idle")
|
|
||||||
const sessionMessages = createMemo(() => (sessionID() ? (sync().data.message[sessionID()!] ?? []) : []))
|
const sessionMessages = createMemo(() => (sessionID() ? (sync().data.message[sessionID()!] ?? []) : []))
|
||||||
const tint = createMemo(() => messageAgentColor(sessionMessages(), sync().data.agent))
|
|
||||||
|
|
||||||
const [timeoutDone, setTimeoutDone] = createSignal(true)
|
|
||||||
|
|
||||||
const workingStatus = createMemo<"hidden" | "showing" | "hiding">((prev) => {
|
|
||||||
if (working()) return "showing"
|
|
||||||
if (prev === "showing" || !timeoutDone()) return "hiding"
|
|
||||||
return "hidden"
|
|
||||||
})
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
if (workingStatus() !== "hiding") return
|
|
||||||
|
|
||||||
setTimeoutDone(false)
|
|
||||||
makeTimer(() => setTimeoutDone(true), 260, setTimeout)
|
|
||||||
})
|
|
||||||
|
|
||||||
const info = createMemo(() => {
|
const info = createMemo(() => {
|
||||||
const id = sessionID()
|
const id = sessionID()
|
||||||
if (!id) return
|
if (!id) return
|
||||||
@@ -1338,23 +1317,6 @@ export function MessageTimeline(props: {
|
|||||||
/
|
/
|
||||||
</span>
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
<div
|
|
||||||
class="shrink-0 flex items-center justify-center overflow-hidden transition-[width,margin] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]"
|
|
||||||
style={{
|
|
||||||
width: working() ? "16px" : "0px",
|
|
||||||
"margin-right": working() ? "8px" : "0px",
|
|
||||||
}}
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<Show when={workingStatus() !== "hidden"}>
|
|
||||||
<div
|
|
||||||
class="transition-opacity duration-200 ease-out"
|
|
||||||
classList={{ "opacity-0": workingStatus() === "hiding" }}
|
|
||||||
>
|
|
||||||
<Spinner class="size-4" style={{ color: tint() ?? "var(--icon-interactive-base)" }} />
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
<Show when={childTitle() || title.editing}>
|
<Show when={childTitle() || title.editing}>
|
||||||
<Show
|
<Show
|
||||||
when={title.editing}
|
when={title.editing}
|
||||||
|
|||||||
Reference in New Issue
Block a user