fix(app): prevent stale session hover preview on refocus (#18727)

This commit is contained in:
Shoubhit Dash 2026-03-23 12:55:30 +05:30 committed by GitHub
parent 9239d877b9
commit 5ea95451dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 29 deletions

View File

@ -211,13 +211,22 @@ export default function Layout(props: ParentProps) {
onMount(() => { onMount(() => {
const stop = () => setState("sizing", false) const stop = () => setState("sizing", false)
const blur = () => reset()
const hide = () => {
if (document.visibilityState !== "hidden") return
reset()
}
window.addEventListener("pointerup", stop) window.addEventListener("pointerup", stop)
window.addEventListener("pointercancel", stop) window.addEventListener("pointercancel", stop)
window.addEventListener("blur", stop) window.addEventListener("blur", stop)
window.addEventListener("blur", blur)
document.addEventListener("visibilitychange", hide)
onCleanup(() => { onCleanup(() => {
window.removeEventListener("pointerup", stop) window.removeEventListener("pointerup", stop)
window.removeEventListener("pointercancel", stop) window.removeEventListener("pointercancel", stop)
window.removeEventListener("blur", stop) window.removeEventListener("blur", stop)
window.removeEventListener("blur", blur)
document.removeEventListener("visibilitychange", hide)
}) })
}) })
@ -237,6 +246,12 @@ export default function Layout(props: ParentProps) {
navLeave.current = undefined navLeave.current = undefined
} }
const reset = () => {
disarm()
setState("hoverSession", undefined)
setHoverProject(undefined)
}
const arm = () => { const arm = () => {
if (layout.sidebar.opened()) return if (layout.sidebar.opened()) return
if (state.hoverProject === undefined) return if (state.hoverProject === undefined) return
@ -305,8 +320,7 @@ export default function Layout(props: ParentProps) {
const clearSidebarHoverState = () => { const clearSidebarHoverState = () => {
if (layout.sidebar.opened()) return if (layout.sidebar.opened()) return
setState("hoverSession", undefined) reset()
setHoverProject(undefined)
} }
const navigateWithSidebarReset = (href: string) => { const navigateWithSidebarReset = (href: string) => {

View File

@ -157,34 +157,45 @@ const SessionHoverPreview = (props: {
messageLabel: (message: Message) => string | undefined messageLabel: (message: Message) => string | undefined
onMessageSelect: (message: Message) => void onMessageSelect: (message: Message) => void
trigger: JSX.Element trigger: JSX.Element
}): JSX.Element => ( }): JSX.Element => {
<HoverCard let ref: HTMLDivElement | undefined
openDelay={1000}
closeDelay={props.sidebarHovering() ? 600 : 0} return (
placement="right-start" <HoverCard
gutter={16} openDelay={1000}
shift={-2} closeDelay={props.sidebarHovering() ? 600 : 0}
trigger={props.trigger} placement="right-start"
open={props.hoverSession() === props.session.id} gutter={16}
onOpenChange={(open) => props.setHoverSession(open ? props.session.id : undefined)} shift={-2}
> trigger={<div ref={ref}>{props.trigger}</div>}
<Show open={props.hoverSession() === props.session.id}
when={props.hoverReady()} onOpenChange={(open) => {
fallback={<div class="text-12-regular text-text-weak">{props.language.t("session.messages.loading")}</div>} if (!open) {
props.setHoverSession(undefined)
return
}
if (!ref?.matches(":hover")) return
props.setHoverSession(props.session.id)
}}
> >
<div class="overflow-y-auto overflow-x-hidden max-h-72 h-full"> <Show
<MessageNav when={props.hoverReady()}
messages={props.hoverMessages() ?? []} fallback={<div class="text-12-regular text-text-weak">{props.language.t("session.messages.loading")}</div>}
current={undefined} >
getLabel={props.messageLabel} <div class="overflow-y-auto overflow-x-hidden max-h-72 h-full">
onMessageSelect={props.onMessageSelect} <MessageNav
size="normal" messages={props.hoverMessages() ?? []}
class="w-60" current={undefined}
/> getLabel={props.messageLabel}
</div> onMessageSelect={props.onMessageSelect}
</Show> size="normal"
</HoverCard> class="w-60"
) />
</div>
</Show>
</HoverCard>
)
}
export const SessionItem = (props: SessionItemProps): JSX.Element => { export const SessionItem = (props: SessionItemProps): JSX.Element => {
const params = useParams() const params = useParams()