feat(desktop): working indicator on project sidebar (#26223)
This commit is contained in:
@@ -26,7 +26,12 @@ export function getProjectAvatarSource(id?: string, icon?: { color?: string; url
|
|||||||
return icon?.url
|
return icon?.url
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProjectIcon = (props: { project: LocalProject; class?: string; notify?: boolean }): JSX.Element => {
|
export const ProjectIcon = (props: {
|
||||||
|
project: LocalProject
|
||||||
|
class?: string
|
||||||
|
notify?: boolean
|
||||||
|
working?: boolean
|
||||||
|
}): JSX.Element => {
|
||||||
const globalSync = useGlobalSync()
|
const globalSync = useGlobalSync()
|
||||||
const notification = useNotification()
|
const notification = useNotification()
|
||||||
const permission = usePermission()
|
const permission = usePermission()
|
||||||
@@ -65,6 +70,11 @@ export const ProjectIcon = (props: { project: LocalProject; class?: string; noti
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
|
<Show when={props.working}>
|
||||||
|
<div class="absolute bottom-px right-px size-3 rounded-full bg-background-base z-10 flex items-center justify-center">
|
||||||
|
<Spinner class="size-[9px]" />
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const ProjectTile = (props: {
|
|||||||
sidebarHovering: Accessor<boolean>
|
sidebarHovering: Accessor<boolean>
|
||||||
selected: Accessor<boolean>
|
selected: Accessor<boolean>
|
||||||
active: Accessor<boolean>
|
active: Accessor<boolean>
|
||||||
|
isWorking: Accessor<boolean>
|
||||||
overlay: Accessor<boolean>
|
overlay: Accessor<boolean>
|
||||||
suppressHover: Accessor<boolean>
|
suppressHover: Accessor<boolean>
|
||||||
dirs: Accessor<string[]>
|
dirs: Accessor<string[]>
|
||||||
@@ -143,7 +144,7 @@ const ProjectTile = (props: {
|
|||||||
}}
|
}}
|
||||||
onBlur={() => props.setOpen(false)}
|
onBlur={() => props.setOpen(false)}
|
||||||
>
|
>
|
||||||
<ProjectIcon project={props.project} notify />
|
<ProjectIcon project={props.project} notify working={props.isWorking()} />
|
||||||
</ContextMenu.Trigger>
|
</ContextMenu.Trigger>
|
||||||
<ContextMenu.Portal>
|
<ContextMenu.Portal>
|
||||||
<ContextMenu.Content>
|
<ContextMenu.Content>
|
||||||
@@ -301,6 +302,12 @@ export const SortableProject = (props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const projectStore = createMemo(() => globalSync.child(props.project.worktree, { bootstrap: false })[0])
|
const projectStore = createMemo(() => globalSync.child(props.project.worktree, { bootstrap: false })[0])
|
||||||
|
const isWorking = createMemo(() =>
|
||||||
|
dirs().some((directory) => {
|
||||||
|
const [store] = globalSync.child(directory, { bootstrap: false })
|
||||||
|
return Object.values(store.session_status).some((status) => status?.type === "busy" || status?.type === "retry")
|
||||||
|
}),
|
||||||
|
)
|
||||||
const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow()))
|
const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow()))
|
||||||
const workspaceSessions = (directory: string) => {
|
const workspaceSessions = (directory: string) => {
|
||||||
const [data] = globalSync.child(directory, { bootstrap: false })
|
const [data] = globalSync.child(directory, { bootstrap: false })
|
||||||
@@ -313,6 +320,7 @@ export const SortableProject = (props: {
|
|||||||
sidebarHovering={props.ctx.sidebarHovering}
|
sidebarHovering={props.ctx.sidebarHovering}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
active={active}
|
active={active}
|
||||||
|
isWorking={isWorking}
|
||||||
overlay={overlay}
|
overlay={overlay}
|
||||||
suppressHover={() => state.suppressHover}
|
suppressHover={() => state.suppressHover}
|
||||||
dirs={dirs}
|
dirs={dirs}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export function DialogSessionList() {
|
|||||||
}
|
}
|
||||||
const isDeleting = toDelete() === x.id
|
const isDeleting = toDelete() === x.id
|
||||||
const status = sync.data.session_status?.[x.id]
|
const status = sync.data.session_status?.[x.id]
|
||||||
const isWorking = status?.type === "busy"
|
const isWorking = status?.type === "busy" || status?.type === "retry"
|
||||||
return {
|
return {
|
||||||
title: isDeleting ? `Press ${deleteHint()} again to confirm` : x.title,
|
title: isDeleting ? `Press ${deleteHint()} again to confirm` : x.title,
|
||||||
bg: isDeleting ? theme.error : undefined,
|
bg: isDeleting ? theme.error : undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user