From de0a0b415e924137dbf6ad59a52a4cbddfd42c87 Mon Sep 17 00:00:00 2001 From: Sebastian Barfurth Date: Tue, 10 Feb 2026 07:16:45 +0000 Subject: [PATCH] Use icons to denote change state in graph. --- package.json | 7 ++++++- src/graphTreeView.ts | 29 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index ce0ac34..f0e09a0 100644 --- a/package.json +++ b/package.json @@ -316,7 +316,12 @@ }, { "command": "jj.abandon", - "when": "view == jjGraph", + "when": "view == jjGraph && viewItem == mutable", + "group": "2_item_action@2" + }, + { + "command": "jj.abandon", + "when": "view == jjGraph && viewItem == mutable", "group": "inline" } ], diff --git a/src/graphTreeView.ts b/src/graphTreeView.ts index b33d352..4ca95fc 100644 --- a/src/graphTreeView.ts +++ b/src/graphTreeView.ts @@ -10,6 +10,7 @@ import { TreeItemLabel, ProviderResult, workspace, + ThemeIcon, } from "vscode"; import { ChangeWithDetails, JJRepository } from "./repository"; import path from "path"; @@ -88,11 +89,13 @@ export class GraphTreeItem extends TreeItem { : TreeItemCollapsibleState.None, ); this.id = this.change.changeId; - if (!this.change.isSynced) { - this.description = "upload needed"; - } else if (this.change.isEmpty) { + this.iconPath = this.getIcon(); + if (this.change.isEmpty) { this.description = "empty"; } + if (!this.change.isImmutable) { + this.contextValue = "mutable"; + } this.tooltip = getChangeTooltip(change); this.command = { command: "jj.update", @@ -123,10 +126,26 @@ export class GraphTreeItem extends TreeItem { equals(other: GraphTreeItem): boolean { return ( - this.change.changeId === other.change.changeId && - this.collapsibleState === other.collapsibleState + this.id === other.id && + this.collapsibleState === other.collapsibleState && + this.iconPath === other.iconPath && + this.description === other.description && + this.contextValue === other.contextValue ); } + + private getIcon(): ThemeIcon | undefined { + if (this.change.isImmutable) { + return new ThemeIcon("lock"); + } + if (!this.change.isSynced) { + return new ThemeIcon("cloud-upload"); + } + if (this.change.bookmarks.length > 0) { + return new ThemeIcon("bookmark"); + } + return undefined; + } } export class GraphTreeDataProvider implements TreeDataProvider {