Compare commits
2 Commits
b3b301b9b6
...
2ae56b2510
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ae56b2510 | |||
| 71fd5f0bb7 |
@@ -1255,3 +1255,10 @@ MIT License
|
||||
- 업데이트: 2026-04-06 15:35 (KST)
|
||||
- AX Agent 내부 설정 공통 탭의 섹션 순서를 다시 정리했다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서 `서비스와 모델` 바로 아래에 `등록 모델 관리`를 연달아 배치해 흐름을 자연스럽게 맞췄다.
|
||||
- `운영 모드`는 `대화 관리 / 대화 보관 기간 / 저장 공간` 아래쪽으로 이동시키고, 섹션 경계도 다시 `BorderThickness="0,0,0,1"` 기반으로 정리해 구분선이 끊기지 않도록 맞췄다.
|
||||
- 업데이트: 2026-04-06 15:41 (KST)
|
||||
- 채팅/코워크 빈 상태 화면의 세로 정렬 기준을 조정했다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서 상단 아이콘, 제목, 설명, 프리셋 목록을 하나의 세로 묶음으로 다시 구성해 화면 높이가 늘어나도 함께 상하 중앙 정렬되도록 수정했다.
|
||||
- 이전처럼 프리셋 카드만 중앙에 오고 상단 설명 블록은 위쪽에 남아 보이던 레이아웃 불균형을 줄여, 빈 상태 화면 전체가 더 자연스럽게 가운데 정렬되도록 맞췄다.
|
||||
- 업데이트: 2026-04-06 15:48 (KST)
|
||||
- 일정 시간마다 표시되는 격려문구 알림 팝업의 자동 닫힘 경로를 점검하고 [ReminderPopupWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ReminderPopupWindow.xaml.cs)를 보강했다.
|
||||
- 기존에는 `DispatcherTimer` 틱만으로 카운트다운과 닫힘을 함께 처리했는데, UI 틱이 밀리면 팝업 종료가 늦어질 여지가 있었다. 이제 카운트다운 표시와 실제 자동 종료를 분리해 `Task.Delay + CancellationToken` 기반 종료를 추가하고, 남은 시간은 절대 시각 기준으로 계산하도록 바꿨다.
|
||||
- 이 변경으로 지정 시간이 지난 뒤에도 격려 팝업이 남아 있는 증상을 줄이고, 자동 닫힘이 더 안정적으로 동작하도록 맞췄다.
|
||||
|
||||
@@ -4964,3 +4964,6 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
||||
- Document update: 2026-04-06 15:26 (KST) - During move-size loops the root visual is temporarily cached with `BitmapCache`, and the expensive `UpdateTopicPresetScrollMode()`, `UpdateResponsiveChatLayout()`, and `RenderMessages()` refresh path is deferred until the move/resize operation ends. This reduces the “heavy” feeling when moving the AX Agent window on desktop PCs.
|
||||
- Document update: 2026-04-06 15:35 (KST) - Reordered the AX Agent internal-settings common tab in `ChatWindow.xaml` so `서비스와 모델` and `등록 모델 관리` now appear consecutively. This matches the actual model-management flow more closely.
|
||||
- Document update: 2026-04-06 15:35 (KST) - Moved the `운영 모드` chooser below the conversation management/storage area and restored section separators around the moved blocks so the common-tab layout reads in clearer grouped sections.
|
||||
- Document update: 2026-04-06 15:41 (KST) - Reworked the empty-state layout in `ChatWindow.xaml` so the icon/title/description block and the preset grid live inside one vertically centered stack. This fixes the previous behavior where only the preset cards looked centered while the descriptive header stayed visually high on tall windows.
|
||||
- Document update: 2026-04-06 15:48 (KST) - Hardened the unlock-reminder popup auto-close path in `ReminderPopupWindow.xaml.cs`. The window now tracks an absolute close deadline and uses a separate `Task.Delay + CancellationToken` fail-safe to close the popup even if the UI timer tick is delayed.
|
||||
- Document update: 2026-04-06 15:48 (KST) - The countdown bar still updates through `DispatcherTimer`, but the actual close action is now guaranteed by the background delay path. This reduces cases where encouragement popups remain visible after the configured display duration.
|
||||
|
||||
@@ -1277,45 +1277,40 @@
|
||||
VerticalAlignment="Stretch"
|
||||
MaxWidth="960"
|
||||
Margin="24,16,24,16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="18"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,8,0,8">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
Margin="0,0,0,18">
|
||||
<Border x:Name="EmptyIcon" CornerRadius="13" Width="46" Height="46"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,12"
|
||||
Background="{DynamicResource HintBackground}">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="22"
|
||||
Foreground="{DynamicResource AccentColor}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<StackPanel Grid.Row="0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Margin="0,14,0,4">
|
||||
<Border x:Name="EmptyIcon" CornerRadius="13" Width="46" Height="46"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,12"
|
||||
Background="{DynamicResource HintBackground}">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="22"
|
||||
Foreground="{DynamicResource AccentColor}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<TextBlock x:Name="EmptyStateTitle" Text="작업을 시작하세요" FontSize="23" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}" HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Name="EmptyStateDesc" Text="프롬프트를 입력하거나 아래 작업 유형을 선택하면 됩니다"
|
||||
FontSize="14.5" Foreground="{DynamicResource SecondaryText}"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
Width="430"
|
||||
Margin="0,7,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Name="EmptyStateTitle" Text="작업을 시작하세요" FontSize="23" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}" HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Name="EmptyStateDesc" Text="프롬프트를 입력하거나 아래 작업 유형을 선택하면 됩니다"
|
||||
FontSize="14.5" Foreground="{DynamicResource SecondaryText}"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
Width="430"
|
||||
Margin="0,7,0,0"/>
|
||||
<ScrollViewer x:Name="TopicPresetScrollViewer"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
MaxHeight="420"
|
||||
Margin="0"
|
||||
Padding="0,4,0,8">
|
||||
<!-- 대화 주제 버튼 (프리셋에서 동적 생성) -->
|
||||
<WrapPanel x:Name="TopicButtonPanel" HorizontalAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer x:Name="TopicPresetScrollViewer"
|
||||
Grid.Row="2"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
MaxHeight="420"
|
||||
Margin="0"
|
||||
Padding="0,4,0,8">
|
||||
<!-- 대화 주제 버튼 (프리셋에서 동적 생성) -->
|
||||
<WrapPanel x:Name="TopicButtonPanel" HorizontalAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<!-- ── 프롬프트 템플릿 팝업 ── -->
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Threading;
|
||||
@@ -26,7 +28,9 @@ public partial class ReminderPopupWindow : Window
|
||||
// ─── 타이머 ───────────────────────────────────────────────────────────────
|
||||
private readonly DispatcherTimer _timer;
|
||||
private readonly EventHandler _tickHandler;
|
||||
private int _remaining;
|
||||
private readonly CancellationTokenSource _autoCloseCts = new();
|
||||
private readonly DateTime _closeAtUtc;
|
||||
private readonly int _displaySeconds;
|
||||
|
||||
public ReminderPopupWindow(
|
||||
string quoteText,
|
||||
@@ -56,9 +60,10 @@ public partial class ReminderPopupWindow : Window
|
||||
: "오늘 방금 시작했습니다";
|
||||
|
||||
// ── 카운트다운 ──
|
||||
_remaining = Math.Max(3, cfg.DisplaySeconds);
|
||||
CountdownBar.Maximum = _remaining;
|
||||
CountdownBar.Value = _remaining;
|
||||
_displaySeconds = Math.Max(3, cfg.DisplaySeconds);
|
||||
_closeAtUtc = DateTime.UtcNow.AddSeconds(_displaySeconds);
|
||||
CountdownBar.Maximum = _displaySeconds;
|
||||
CountdownBar.Value = _displaySeconds;
|
||||
|
||||
// ── 위치: 레이아웃 완료 후 설정 ──
|
||||
Loaded += (_, _) =>
|
||||
@@ -71,13 +76,15 @@ public partial class ReminderPopupWindow : Window
|
||||
// ── 타이머 ──
|
||||
_tickHandler = (_, _) =>
|
||||
{
|
||||
_remaining--;
|
||||
CountdownBar.Value = _remaining;
|
||||
if (_remaining <= 0) Close();
|
||||
var remainingSeconds = Math.Max(0, (_closeAtUtc - DateTime.UtcNow).TotalSeconds);
|
||||
CountdownBar.Value = remainingSeconds;
|
||||
if (remainingSeconds <= 0)
|
||||
Close();
|
||||
};
|
||||
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
|
||||
_timer.Tick += _tickHandler;
|
||||
_timer.Start();
|
||||
_ = StartAutoCloseAsync(_autoCloseCts.Token);
|
||||
|
||||
// ── Esc 키 닫기 ──
|
||||
KeyDown += (_, e) =>
|
||||
@@ -132,10 +139,34 @@ public partial class ReminderPopupWindow : Window
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
private async Task StartAutoCloseAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(_displaySeconds), cancellationToken);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
if (IsVisible)
|
||||
Close();
|
||||
}, DispatcherPriority.Background, cancellationToken);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
_autoCloseCts.Cancel();
|
||||
_timer.Stop();
|
||||
_timer.Tick -= _tickHandler;
|
||||
_autoCloseCts.Dispose();
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user