From 85b5f5b705e8f7852184a4ef147bdc826639d224 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sat, 14 Feb 2026 19:33:22 -0600 Subject: feat(app): clear notifications action (#13668) Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com> --- packages/app/src/pages/layout.tsx | 17 +++ packages/app/src/pages/layout/sidebar-project.tsx | 155 +++++++++++++--------- 2 files changed, 107 insertions(+), 65 deletions(-) (limited to 'packages/app/src/pages') diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 7eb064f42..7d4a5c0cb 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -1692,6 +1692,13 @@ export default function Layout(props: ParentProps) { }) const projectId = createMemo(() => panelProps.project?.id ?? "") const workspaces = createMemo(() => workspaceIds(panelProps.project)) + const unseenCount = createMemo(() => + workspaces().reduce((total, directory) => total + notification.project.unseenCount(directory), 0), + ) + const clearNotifications = () => + workspaces() + .filter((directory) => notification.project.unseenCount(directory) > 0) + .forEach((directory) => notification.project.markViewed(directory)) const workspacesEnabled = createMemo(() => { const project = panelProps.project if (!project) return false @@ -1769,6 +1776,16 @@ export default function Layout(props: ParentProps) { : language.t("sidebar.workspaces.enable")} + + + {language.t("sidebar.project.clearNotifications")} + + active: Accessor overlay: Accessor + dirs: Accessor onProjectMouseEnter: (worktree: string, event: MouseEvent) => void onProjectMouseLeave: (worktree: string) => void onProjectFocus: (worktree: string) => void @@ -70,73 +72,94 @@ const ProjectTile = (props: { setMenu: (value: boolean) => void setOpen: (value: boolean) => void language: ReturnType -}): JSX.Element => ( - { - props.setMenu(value) - if (value) props.setOpen(false) - }} - > - { - if (!props.overlay()) return - props.onProjectMouseEnter(props.project.worktree, event) - }} - onMouseLeave={() => { - if (!props.overlay()) return - props.onProjectMouseLeave(props.project.worktree) - }} - onFocus={() => { - if (!props.overlay()) return - props.onProjectFocus(props.project.worktree) +}): JSX.Element => { + const notification = useNotification() + const unseenCount = createMemo(() => + props.dirs().reduce((total, directory) => total + notification.project.unseenCount(directory), 0), + ) + + const clear = () => + props + .dirs() + .filter((directory) => notification.project.unseenCount(directory) > 0) + .forEach((directory) => notification.project.markViewed(directory)) + + return ( + { + props.setMenu(value) + if (value) props.setOpen(false) }} - onClick={() => props.navigateToProject(props.project.worktree)} - onBlur={() => props.setOpen(false)} > - - - - - props.showEditProjectDialog(props.project)}> - {props.language.t("common.edit")} - - props.toggleProjectWorkspaces(props.project)} - > - - {props.workspacesEnabled(props.project) - ? props.language.t("sidebar.workspaces.disable") - : props.language.t("sidebar.workspaces.enable")} - - - - props.closeProject(props.project.worktree)} - > - {props.language.t("common.close")} - - - - -) + { + if (!props.overlay()) return + props.onProjectMouseEnter(props.project.worktree, event) + }} + onMouseLeave={() => { + if (!props.overlay()) return + props.onProjectMouseLeave(props.project.worktree) + }} + onFocus={() => { + if (!props.overlay()) return + props.onProjectFocus(props.project.worktree) + }} + onClick={() => props.navigateToProject(props.project.worktree)} + onBlur={() => props.setOpen(false)} + > + + + + + props.showEditProjectDialog(props.project)}> + {props.language.t("common.edit")} + + props.toggleProjectWorkspaces(props.project)} + > + + {props.workspacesEnabled(props.project) + ? props.language.t("sidebar.workspaces.disable") + : props.language.t("sidebar.workspaces.enable")} + + + + {props.language.t("sidebar.project.clearNotifications")} + + + props.closeProject(props.project.worktree)} + > + {props.language.t("common.close")} + + + + + ) +} const ProjectPreviewPanel = (props: { project: LocalProject @@ -254,6 +277,7 @@ export const SortableProject = (props: { ) const workspaces = createMemo(() => props.ctx.workspaceIds(props.project).slice(0, 2)) const workspaceEnabled = createMemo(() => props.ctx.workspacesEnabled(props.project)) + const dirs = createMemo(() => props.ctx.workspaceIds(props.project)) const [open, setOpen] = createSignal(false) const [menu, setMenu] = createSignal(false) @@ -304,6 +328,7 @@ export const SortableProject = (props: { selected={selected} active={active} overlay={overlay} + dirs={dirs} onProjectMouseEnter={props.ctx.onProjectMouseEnter} onProjectMouseLeave={props.ctx.onProjectMouseLeave} onProjectFocus={props.ctx.onProjectFocus} -- cgit v1.2.3