코드 탭 Git 브랜치 선택 UI 단순화
- 하단 Git 브랜치 버튼을 상태판형에서 브랜치 선택 버튼 형태로 정리\n- 브랜치 버튼 기본 노출에서 변경 파일/추가/삭제 수치를 숨기고 브랜치명 중심으로 단순화\n- README 및 DEVELOPMENT 문서 이력 갱신\n\n검증:\n- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\\n- 경고 0 / 오류 0
This commit is contained in:
@@ -7,6 +7,9 @@ Windows 전용 시맨틱 런처 & 워크스페이스 매니저
|
|||||||
개발 참고: Claw Code 동등성 작업 추적 문서
|
개발 참고: Claw Code 동등성 작업 추적 문서
|
||||||
`docs/claw-code-parity-plan.md`
|
`docs/claw-code-parity-plan.md`
|
||||||
|
|
||||||
|
- 업데이트: 2026-04-06 00:50 (KST)
|
||||||
|
- 채팅/코워크 프리셋 카드의 hover 설명 레이어를 카드 내부 오버레이 방식에서 안정적인 tooltip형 설명으로 바꿨습니다. 카드 배경/테두리만 반응하게 정리해 hover 시 반복 깜빡임을 줄였습니다.
|
||||||
|
|
||||||
- 업데이트: 2026-04-06 00:45 (KST)
|
- 업데이트: 2026-04-06 00:45 (KST)
|
||||||
- AX Agent 내부 설정 공통 탭에 `대화 스타일` 섹션 제목을 복구해, `문서 형태`와 `디자인 스타일` 저장 항목이 명확히 보이도록 정리했습니다.
|
- AX Agent 내부 설정 공통 탭에 `대화 스타일` 섹션 제목을 복구해, `문서 형태`와 `디자인 스타일` 저장 항목이 명확히 보이도록 정리했습니다.
|
||||||
- AX Agent 내부 설정 스킬 탭의 `MCP 서버` 영역에 `서버 추가` 버튼을 복원했고, 목록 카드 안에서 `활성화/비활성화`와 `삭제`까지 바로 관리할 수 있게 옮겼습니다.
|
- AX Agent 내부 설정 스킬 탭의 `MCP 서버` 영역에 `서버 추가` 버튼을 복원했고, 목록 카드 안에서 `활성화/비활성화`와 `삭제`까지 바로 관리할 수 있게 옮겼습니다.
|
||||||
@@ -1094,3 +1097,7 @@ MIT License
|
|||||||
- `claw-code`의 `SessionPreview`/`PreviewBox` 흐름을 참고해 AX Agent 프리뷰도 같은 시각 언어로 정리했다. 새 파일 [AgentPreviewSurfaceFactory.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/AgentPreviewSurfaceFactory.cs)를 추가해 권한 프리뷰 카드의 제목/요약/본문 박스 구조를 공통화했다.
|
- `claw-code`의 `SessionPreview`/`PreviewBox` 흐름을 참고해 AX Agent 프리뷰도 같은 시각 언어로 정리했다. 새 파일 [AgentPreviewSurfaceFactory.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/AgentPreviewSurfaceFactory.cs)를 추가해 권한 프리뷰 카드의 제목/요약/본문 박스 구조를 공통화했다.
|
||||||
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs)의 일반 프리뷰, 파일 편집 프리뷰, 파일 생성 2열 프리뷰를 이 공통 surface로 맞춰 `preview box` 언어를 통일했다.
|
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs)의 일반 프리뷰, 파일 편집 프리뷰, 파일 생성 2열 프리뷰를 이 공통 surface로 맞춰 `preview box` 언어를 통일했다.
|
||||||
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml), [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 우측 파일 프리뷰 패널에는 파일명/경로/형식·크기 메타를 보여주는 헤더를 추가하고, 텍스트 프리뷰 본문도 별도 bordered preview box 안에 렌더되게 바꿨다.
|
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml), [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 우측 파일 프리뷰 패널에는 파일명/경로/형식·크기 메타를 보여주는 헤더를 추가하고, 텍스트 프리뷰 본문도 별도 bordered preview box 안에 렌더되게 바꿨다.
|
||||||
|
- 업데이트: 2026-04-06 00:35 (KST)
|
||||||
|
- AX Agent 채팅/코워크 프리셋 카드에서 기본 ToolTip을 제거해 hover 시 깜빡이듯 반복되던 현상을 줄였습니다.
|
||||||
|
- 업데이트: 2026-04-06 00:42 (KST)
|
||||||
|
- 코드 탭 하단 Git 브랜치 버튼을 상태판 형태에서 단순한 브랜치 선택 버튼 형태로 정리했습니다.
|
||||||
|
|||||||
@@ -4851,5 +4851,11 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs) 의 `BuildPreviewCard`, `BuildFileEditPreviewCard`, `BuildFileWriteTwoColumnPreviewCard`는 이 helper를 쓰도록 정리해 권한 승인 프리뷰가 같은 preview 언어를 따르도록 맞췄다.
|
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs) 의 `BuildPreviewCard`, `BuildFileEditPreviewCard`, `BuildFileWriteTwoColumnPreviewCard`는 이 helper를 쓰도록 정리해 권한 승인 프리뷰가 같은 preview 언어를 따르도록 맞췄다.
|
||||||
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 우측 프리뷰 패널 헤더를 `파일명 / 경로 / 형식·크기 메타` 구조로 재배치하고, [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에 `SetPreviewHeader`, `SetPreviewHeaderState`를 추가해 현재 탭 파일 메타를 표시하도록 했다.
|
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 우측 프리뷰 패널 헤더를 `파일명 / 경로 / 형식·크기 메타` 구조로 재배치하고, [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에 `SetPreviewHeader`, `SetPreviewHeaderState`를 추가해 현재 탭 파일 메타를 표시하도록 했다.
|
||||||
- 텍스트 프리뷰 본문도 bordered preview box 안에 렌더되게 바꿔, AX Agent 파일 프리뷰와 transcript/승인 프리뷰 사이 시각 언어를 더 가깝게 맞췄다.
|
- 텍스트 프리뷰 본문도 bordered preview box 안에 렌더되게 바꿔, AX Agent 파일 프리뷰와 transcript/승인 프리뷰 사이 시각 언어를 더 가깝게 맞췄다.
|
||||||
|
- Document update: 2026-04-06 00:50 (KST) - Reworked Chat/Cowork preset hover behavior in `BuildTopicButtons()`. The previous inline hover label overlay was removed and replaced with a stable tooltip-style description so preset cards only change background/border on hover, eliminating the repeated flicker effect caused by overlay-style label toggling.
|
||||||
|
|
||||||
- Document update: 2026-04-06 00:45 (KST) - Restored the missing AX Agent internal-settings UX for conversation-style persistence by adding a visible `대화 스타일` section header above the existing `문서 형태` and `디자인 스타일` controls. The underlying save path already existed in `CmbOverlayDefaultOutputFormat_SelectionChanged` and `CmbOverlayDefaultMood_SelectionChanged`; this pass makes that persisted behavior explicit again in the overlay.
|
- Document update: 2026-04-06 00:45 (KST) - Restored the missing AX Agent internal-settings UX for conversation-style persistence by adding a visible `대화 스타일` section header above the existing `문서 형태` and `디자인 스타일` controls. The underlying save path already existed in `CmbOverlayDefaultOutputFormat_SelectionChanged` and `CmbOverlayDefaultMood_SelectionChanged`; this pass makes that persisted behavior explicit again in the overlay.
|
||||||
- Document update: 2026-04-06 00:45 (KST) - Restored MCP server management inside the AX Agent internal settings overlay. The skill tab now exposes `+ 서버 추가`, and overlay MCP cards support inline enable/disable and delete actions with immediate persistence through `PersistOverlaySettingsState(...)`.
|
- Document update: 2026-04-06 00:45 (KST) - Restored MCP server management inside the AX Agent internal settings overlay. The skill tab now exposes `+ 서버 추가`, and overlay MCP cards support inline enable/disable and delete actions with immediate persistence through `PersistOverlaySettingsState(...)`.
|
||||||
|
- 업데이트: 2026-04-06 00:35 (KST)
|
||||||
|
- `ChatWindow.xaml.cs`의 프리셋 카드 hover 처리에서 WPF 기본 ToolTip을 제거했습니다. 이제 hover는 배경/테두리만 바뀌고 tooltip에 의한 enter/leave 반복이 줄어듭니다.
|
||||||
|
- 업데이트: 2026-04-06 00:42 (KST)
|
||||||
|
- `ChatWindow` 하단 Git 브랜치 UI를 단순화했습니다. 변경 파일 수/추가/삭제 수치는 기본 버튼에서는 숨기고 브랜치명 중심의 선택 버튼처럼 보이게 조정했습니다.
|
||||||
|
|||||||
@@ -2245,11 +2245,11 @@
|
|||||||
Margin="2,0,0,0"
|
Margin="2,0,0,0"
|
||||||
Visibility="Collapsed"
|
Visibility="Collapsed"
|
||||||
Click="BtnGitBranch_Click"
|
Click="BtnGitBranch_Click"
|
||||||
ToolTip="현재 Git 브랜치 상태">
|
ToolTip="Git 브랜치 선택">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text=""
|
<TextBlock Text=""
|
||||||
FontFamily="Segoe MDL2 Assets"
|
FontFamily="Segoe MDL2 Assets"
|
||||||
FontSize="12"
|
FontSize="12.5"
|
||||||
Foreground="{DynamicResource SecondaryText}"
|
Foreground="{DynamicResource SecondaryText}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Margin="0,0,4,0"/>
|
Margin="0,0,4,0"/>
|
||||||
@@ -2260,18 +2260,21 @@
|
|||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
<TextBlock x:Name="GitBranchFilesText"
|
<TextBlock x:Name="GitBranchFilesText"
|
||||||
Text=""
|
Text=""
|
||||||
|
Visibility="Collapsed"
|
||||||
FontSize="11"
|
FontSize="11"
|
||||||
Foreground="{DynamicResource SecondaryText}"
|
Foreground="{DynamicResource SecondaryText}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Margin="6,0,0,0"/>
|
Margin="6,0,0,0"/>
|
||||||
<TextBlock x:Name="GitBranchAddedText"
|
<TextBlock x:Name="GitBranchAddedText"
|
||||||
Text=""
|
Text=""
|
||||||
|
Visibility="Collapsed"
|
||||||
FontSize="11"
|
FontSize="11"
|
||||||
Foreground="#16A34A"
|
Foreground="#16A34A"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Margin="6,0,0,0"/>
|
Margin="6,0,0,0"/>
|
||||||
<TextBlock x:Name="GitBranchDeletedText"
|
<TextBlock x:Name="GitBranchDeletedText"
|
||||||
Text=""
|
Text=""
|
||||||
|
Visibility="Collapsed"
|
||||||
FontSize="11"
|
FontSize="11"
|
||||||
Foreground="#DC2626"
|
Foreground="#DC2626"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -3250,9 +3253,103 @@
|
|||||||
Background="{DynamicResource LauncherBackground}"
|
Background="{DynamicResource LauncherBackground}"
|
||||||
BorderBrush="{DynamicResource BorderColor}"
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Foreground="{DynamicResource PrimaryText}"
|
Foreground="{DynamicResource PrimaryText}"
|
||||||
FontSize="12"/>
|
FontSize="12"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<StackPanel Margin="0,2,0,12">
|
||||||
|
<TextBlock Text="대화 관리"
|
||||||
|
FontSize="13"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="대화 보관 기간과 저장 공간 정리를 여기서 바로 관리합니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Grid Margin="0,0,0,10">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="0,0,12,0">
|
||||||
|
<TextBlock Text="대화 보관 기간"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="설정 기간이 지나면 오래된 대화는 자동으로 정리됩니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<WrapPanel Grid.Column="1" HorizontalAlignment="Right">
|
||||||
|
<Button x:Name="BtnOverlayRetention7"
|
||||||
|
Content="7일"
|
||||||
|
Padding="10,6"
|
||||||
|
Margin="0,0,6,0"
|
||||||
|
Click="BtnOverlayRetention_Click"/>
|
||||||
|
<Button x:Name="BtnOverlayRetention30"
|
||||||
|
Content="30일"
|
||||||
|
Padding="10,6"
|
||||||
|
Margin="0,0,6,0"
|
||||||
|
Click="BtnOverlayRetention_Click"/>
|
||||||
|
<Button x:Name="BtnOverlayRetention90"
|
||||||
|
Content="90일"
|
||||||
|
Padding="10,6"
|
||||||
|
Margin="0,0,6,0"
|
||||||
|
Click="BtnOverlayRetention_Click"/>
|
||||||
|
<Button x:Name="BtnOverlayRetentionUnlimited"
|
||||||
|
Content="무제한"
|
||||||
|
Padding="10,6"
|
||||||
|
Click="BtnOverlayRetention_Click"/>
|
||||||
|
</WrapPanel>
|
||||||
|
</Grid>
|
||||||
|
<Border Background="{DynamicResource ItemBackground}"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="12"
|
||||||
|
Padding="14,12"
|
||||||
|
Margin="0,0,0,12">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="저장 공간"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock x:Name="OverlayStorageSummaryText"
|
||||||
|
Text="분석 중..."
|
||||||
|
Margin="0,6,0,0"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock x:Name="OverlayStorageDriveText"
|
||||||
|
Margin="0,3,0,0"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Column="1"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
<Button x:Name="BtnOverlayStorageRefresh"
|
||||||
|
Content="새로고침"
|
||||||
|
Padding="10,6"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
Click="BtnOverlayStorageRefresh_Click"/>
|
||||||
|
<Button x:Name="BtnOverlayDeleteAllConversations"
|
||||||
|
Content="대화 삭제"
|
||||||
|
Padding="10,6"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
Click="BtnOverlayDeleteAllConversations_Click"/>
|
||||||
|
<Button x:Name="BtnOverlayStorageCleanup"
|
||||||
|
Content="저장 공간 줄이기"
|
||||||
|
Padding="12,6"
|
||||||
|
Click="BtnOverlayStorageCleanup_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
<Border x:Name="OverlayToggleImageInput" Style="{StaticResource OverlayAdvancedToggleRowStyle}">
|
<Border x:Name="OverlayToggleImageInput" Style="{StaticResource OverlayAdvancedToggleRowStyle}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -12244,7 +12244,7 @@ public partial class ChatWindow : Window
|
|||||||
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.White;
|
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.White;
|
||||||
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
|
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
|
||||||
|
|
||||||
void AttachTopicCardHover(Border card, Border hoverLabel, Brush normalBackground, Brush hoverBackground)
|
void AttachTopicCardHover(Border card, Brush normalBackground, Brush hoverBackground)
|
||||||
{
|
{
|
||||||
card.MouseEnter += (s, _) =>
|
card.MouseEnter += (s, _) =>
|
||||||
{
|
{
|
||||||
@@ -12253,7 +12253,6 @@ public partial class ChatWindow : Window
|
|||||||
b.Background = hoverBackground;
|
b.Background = hoverBackground;
|
||||||
b.BorderBrush = TryFindResource("AccentColor") as Brush ?? cardBorder;
|
b.BorderBrush = TryFindResource("AccentColor") as Brush ?? cardBorder;
|
||||||
}
|
}
|
||||||
hoverLabel.Opacity = 1;
|
|
||||||
};
|
};
|
||||||
card.MouseLeave += (s, _) =>
|
card.MouseLeave += (s, _) =>
|
||||||
{
|
{
|
||||||
@@ -12262,7 +12261,6 @@ public partial class ChatWindow : Window
|
|||||||
b.Background = normalBackground;
|
b.Background = normalBackground;
|
||||||
b.BorderBrush = cardBorder;
|
b.BorderBrush = cardBorder;
|
||||||
}
|
}
|
||||||
hoverLabel.Opacity = 0;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12324,31 +12322,6 @@ public partial class ChatWindow : Window
|
|||||||
MaxWidth = 112,
|
MaxWidth = 112,
|
||||||
});
|
});
|
||||||
|
|
||||||
var hoverLabel = new Border
|
|
||||||
{
|
|
||||||
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
|
|
||||||
BorderBrush = cardBorder,
|
|
||||||
BorderThickness = new Thickness(1),
|
|
||||||
CornerRadius = new CornerRadius(8),
|
|
||||||
Padding = new Thickness(8, 4, 8, 4),
|
|
||||||
Margin = new Thickness(8, 0, 8, 6),
|
|
||||||
VerticalAlignment = VerticalAlignment.Bottom,
|
|
||||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
||||||
Visibility = Visibility.Visible,
|
|
||||||
Opacity = 0,
|
|
||||||
IsHitTestVisible = false,
|
|
||||||
Child = new TextBlock
|
|
||||||
{
|
|
||||||
Text = preset.Description,
|
|
||||||
FontSize = 11.5,
|
|
||||||
TextWrapping = TextWrapping.Wrap,
|
|
||||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
|
||||||
MaxHeight = 34,
|
|
||||||
Foreground = secondaryText,
|
|
||||||
TextAlignment = TextAlignment.Center,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 커스텀 프리셋: 좌측 상단 뱃지
|
// 커스텀 프리셋: 좌측 상단 뱃지
|
||||||
if (capturedPreset.IsCustom)
|
if (capturedPreset.IsCustom)
|
||||||
{
|
{
|
||||||
@@ -12378,10 +12351,8 @@ public partial class ChatWindow : Window
|
|||||||
contentGrid.Children.Add(stack);
|
contentGrid.Children.Add(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
contentGrid.Children.Add(hoverLabel);
|
|
||||||
border.Child = contentGrid;
|
border.Child = contentGrid;
|
||||||
AttachTopicCardHover(border, hoverLabel, cardBackground, cardHoverBackground);
|
AttachTopicCardHover(border, cardBackground, cardHoverBackground);
|
||||||
|
|
||||||
// 클릭 → 해당 주제로 새 대화 시작
|
// 클릭 → 해당 주제로 새 대화 시작
|
||||||
border.MouseLeftButtonDown += (_, _) => SelectTopic(capturedPreset);
|
border.MouseLeftButtonDown += (_, _) => SelectTopic(capturedPreset);
|
||||||
|
|
||||||
@@ -12450,36 +12421,9 @@ public partial class ChatWindow : Window
|
|||||||
HorizontalAlignment = HorizontalAlignment.Center,
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
TextAlignment = TextAlignment.Center,
|
TextAlignment = TextAlignment.Center,
|
||||||
});
|
});
|
||||||
var etcHoverLabel = new Border
|
|
||||||
{
|
|
||||||
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
|
|
||||||
BorderBrush = cardBorder,
|
|
||||||
BorderThickness = new Thickness(1),
|
|
||||||
CornerRadius = new CornerRadius(8),
|
|
||||||
Padding = new Thickness(8, 4, 8, 4),
|
|
||||||
Margin = new Thickness(8, 0, 8, 6),
|
|
||||||
VerticalAlignment = VerticalAlignment.Bottom,
|
|
||||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
||||||
Visibility = Visibility.Visible,
|
|
||||||
Opacity = 0,
|
|
||||||
IsHitTestVisible = false,
|
|
||||||
Child = new TextBlock
|
|
||||||
{
|
|
||||||
Text = "프리셋 없이 자유롭게 대화합니다",
|
|
||||||
FontSize = 11.5,
|
|
||||||
TextWrapping = TextWrapping.Wrap,
|
|
||||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
|
||||||
MaxHeight = 34,
|
|
||||||
Foreground = secondaryText,
|
|
||||||
TextAlignment = TextAlignment.Center,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
etcGrid.Children.Add(etcStack);
|
etcGrid.Children.Add(etcStack);
|
||||||
etcGrid.Children.Add(etcHoverLabel);
|
|
||||||
etcBorder.Child = etcGrid;
|
etcBorder.Child = etcGrid;
|
||||||
AttachTopicCardHover(etcBorder, etcHoverLabel, cardBackground, cardHoverBackground);
|
AttachTopicCardHover(etcBorder, cardBackground, cardHoverBackground);
|
||||||
|
|
||||||
etcBorder.MouseLeftButtonDown += (_, _) =>
|
etcBorder.MouseLeftButtonDown += (_, _) =>
|
||||||
{
|
{
|
||||||
EmptyState.Visibility = Visibility.Collapsed;
|
EmptyState.Visibility = Visibility.Collapsed;
|
||||||
@@ -12529,35 +12473,9 @@ public partial class ChatWindow : Window
|
|||||||
HorizontalAlignment = HorizontalAlignment.Center,
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
});
|
});
|
||||||
|
|
||||||
var addHoverLabel = new Border
|
|
||||||
{
|
|
||||||
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
|
|
||||||
BorderBrush = cardBorder,
|
|
||||||
BorderThickness = new Thickness(1),
|
|
||||||
CornerRadius = new CornerRadius(8),
|
|
||||||
Padding = new Thickness(8, 4, 8, 4),
|
|
||||||
Margin = new Thickness(8, 0, 8, 6),
|
|
||||||
VerticalAlignment = VerticalAlignment.Bottom,
|
|
||||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
||||||
Visibility = Visibility.Visible,
|
|
||||||
Opacity = 0,
|
|
||||||
IsHitTestVisible = false,
|
|
||||||
Child = new TextBlock
|
|
||||||
{
|
|
||||||
Text = "새 작업 유형 카드를 직접 추가합니다",
|
|
||||||
FontSize = 11.5,
|
|
||||||
TextWrapping = TextWrapping.Wrap,
|
|
||||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
|
||||||
MaxHeight = 34,
|
|
||||||
Foreground = secondaryText,
|
|
||||||
TextAlignment = TextAlignment.Center,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addGrid.Children.Add(addStack);
|
addGrid.Children.Add(addStack);
|
||||||
addGrid.Children.Add(addHoverLabel);
|
|
||||||
addBorder.Child = addGrid;
|
addBorder.Child = addGrid;
|
||||||
AttachTopicCardHover(addBorder, addHoverLabel, Brushes.Transparent, cardHoverBackground);
|
AttachTopicCardHover(addBorder, Brushes.Transparent, cardHoverBackground);
|
||||||
addBorder.MouseLeftButtonDown += (_, _) => ShowCustomPresetDialog();
|
addBorder.MouseLeftButtonDown += (_, _) => ShowCustomPresetDialog();
|
||||||
TopicButtonPanel.Children.Add(addBorder);
|
TopicButtonPanel.Children.Add(addBorder);
|
||||||
}
|
}
|
||||||
@@ -14617,6 +14535,8 @@ public partial class ChatWindow : Window
|
|||||||
RefreshOverlayServiceFieldVisibility(service);
|
RefreshOverlayServiceFieldVisibility(service);
|
||||||
BuildOverlayRegisteredModelsPanel(service);
|
BuildOverlayRegisteredModelsPanel(service);
|
||||||
RefreshOverlayAdvancedChoiceButtons();
|
RefreshOverlayAdvancedChoiceButtons();
|
||||||
|
RefreshOverlayRetentionButtons();
|
||||||
|
RefreshOverlayStorageSummary();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -15368,6 +15288,117 @@ public partial class ChatWindow : Window
|
|||||||
RefreshOverlayEtcPanels();
|
RefreshOverlayEtcPanels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RefreshOverlayRetentionButtons()
|
||||||
|
{
|
||||||
|
ApplyOverlayRetentionButtonState(BtnOverlayRetention7, _settings.Settings.Llm.RetentionDays == 7);
|
||||||
|
ApplyOverlayRetentionButtonState(BtnOverlayRetention30, _settings.Settings.Llm.RetentionDays == 30);
|
||||||
|
ApplyOverlayRetentionButtonState(BtnOverlayRetention90, _settings.Settings.Llm.RetentionDays == 90);
|
||||||
|
ApplyOverlayRetentionButtonState(BtnOverlayRetentionUnlimited, _settings.Settings.Llm.RetentionDays == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyOverlayRetentionButtonState(Button? button, bool selected)
|
||||||
|
{
|
||||||
|
if (button == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var accent = TryFindResource("AccentColor") as Brush ?? Brushes.DodgerBlue;
|
||||||
|
var border = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray;
|
||||||
|
var hint = TryFindResource("HintBackground") as Brush ?? Brushes.Transparent;
|
||||||
|
var primary = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
|
||||||
|
var secondary = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
|
||||||
|
|
||||||
|
button.Background = selected ? hint : Brushes.Transparent;
|
||||||
|
button.BorderBrush = selected ? accent : border;
|
||||||
|
button.BorderThickness = new Thickness(1);
|
||||||
|
button.Foreground = selected ? accent : primary;
|
||||||
|
button.FontWeight = selected ? FontWeights.SemiBold : FontWeights.Normal;
|
||||||
|
button.Cursor = Cursors.Hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshOverlayStorageSummary()
|
||||||
|
{
|
||||||
|
if (OverlayStorageSummaryText == null || OverlayStorageDriveText == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var report = StorageAnalyzer.Analyze();
|
||||||
|
var appTotal = report.Conversations + report.AuditLogs + report.Logs + report.CodeIndex + report.EmbeddingDb + report.ClipboardHistory + report.Plugins + report.Skills + report.Settings;
|
||||||
|
OverlayStorageSummaryText.Text = $"앱 전체 사용량: {FormatStorageBytes(appTotal)}";
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(report.DriveLabel) && report.DriveTotalSpace > 0)
|
||||||
|
{
|
||||||
|
var used = report.DriveTotalSpace - report.DriveFreeSpace;
|
||||||
|
var percent = report.DriveTotalSpace == 0 ? 0 : (int)Math.Round((double)used / report.DriveTotalSpace * 100);
|
||||||
|
OverlayStorageDriveText.Text = $"{report.DriveLabel} · 사용 {percent}% · 여유 {FormatStorageBytes(report.DriveFreeSpace)}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OverlayStorageDriveText.Text = "로컬 앱 데이터 폴더 기준 사용량입니다.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnOverlayRetention_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not FrameworkElement element)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var retainDays = element.Name switch
|
||||||
|
{
|
||||||
|
"BtnOverlayRetention7" => 7,
|
||||||
|
"BtnOverlayRetention30" => 30,
|
||||||
|
"BtnOverlayRetention90" => 90,
|
||||||
|
"BtnOverlayRetentionUnlimited" => 0,
|
||||||
|
_ => _settings.Settings.Llm.RetentionDays
|
||||||
|
};
|
||||||
|
|
||||||
|
_settings.Settings.Llm.RetentionDays = retainDays;
|
||||||
|
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||||
|
RefreshOverlayRetentionButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnOverlayStorageRefresh_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
RefreshOverlayStorageSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnOverlayDeleteAllConversations_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
BtnDeleteAll_Click(sender, e);
|
||||||
|
RefreshOverlayStorageSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnOverlayStorageCleanup_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var retainDays = Math.Max(0, _settings.Settings.Llm.RetentionDays);
|
||||||
|
var cleanedBytes = StorageAnalyzer.Cleanup(
|
||||||
|
retainDays,
|
||||||
|
cleanConversations: false,
|
||||||
|
cleanAuditLogs: true,
|
||||||
|
cleanLogs: true,
|
||||||
|
cleanCodeIndex: true,
|
||||||
|
cleanClipboard: true);
|
||||||
|
|
||||||
|
RefreshOverlayStorageSummary();
|
||||||
|
|
||||||
|
CustomMessageBox.Show(
|
||||||
|
cleanedBytes > 0
|
||||||
|
? $"저장 공간을 정리했습니다.\n확보된 공간: {StorageAnalyzer.FormatSize(cleanedBytes)}"
|
||||||
|
: "정리할 항목이 없었습니다.",
|
||||||
|
"저장 공간 정리",
|
||||||
|
MessageBoxButton.OK,
|
||||||
|
MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatStorageBytes(long bytes)
|
||||||
|
{
|
||||||
|
if (bytes >= 1024L * 1024 * 1024)
|
||||||
|
return $"{bytes / 1024.0 / 1024 / 1024:F1} GB";
|
||||||
|
if (bytes >= 1024L * 1024)
|
||||||
|
return $"{bytes / 1024.0 / 1024:F1} MB";
|
||||||
|
if (bytes >= 1024L)
|
||||||
|
return $"{bytes / 1024.0:F0} KB";
|
||||||
|
return $"{bytes} B";
|
||||||
|
}
|
||||||
|
|
||||||
private void RefreshOverlayEtcPanels()
|
private void RefreshOverlayEtcPanels()
|
||||||
{
|
{
|
||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
@@ -19234,7 +19265,7 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GitBranchLabel != null)
|
if (GitBranchLabel != null)
|
||||||
GitBranchLabel.Text = string.IsNullOrWhiteSpace(branchName) ? "브랜치 없음" : $"브랜치 {branchName}";
|
GitBranchLabel.Text = string.IsNullOrWhiteSpace(branchName) ? "브랜치 없음" : branchName;
|
||||||
if (GitBranchFilesText != null)
|
if (GitBranchFilesText != null)
|
||||||
GitBranchFilesText.Text = filesText;
|
GitBranchFilesText.Text = filesText;
|
||||||
if (GitBranchAddedText != null)
|
if (GitBranchAddedText != null)
|
||||||
|
|||||||
Reference in New Issue
Block a user