Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ và dự án tuân theo [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Added / Feature
- **Motivation Quote UI**: Triển khai hiển thị câu chữ truyền động lực (Motivation Quote) bên dưới đồng hồ đếm ngược. UI tự động gọi AI lấy câu quote (theo database hoặc fallback) dựa trên các cột mốc chiến lược: `PreFocus` (bắt đầu ngẫu nhiên), `MidFocus` (qua 50% thời gian), và `PostFocus` (gần hoàn thành, vượt 90%). Khi khôi phục phiên sẽ hiển thị quote giữ lửa cố định.

---

## [1.0.3] - 2026-04-17
Expand Down
27 changes: 27 additions & 0 deletions src/DontBeLazy.WPF/ViewModels/FocusSessionViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public partial class FocusSessionViewModel : ObservableObject
public bool CanConfirmAbandon => FrictionInput.Trim() == FrictionPhrase;

private int _totalSeconds;
private bool _hasShownMidFocus;
private bool _hasShownPostFocus;

[ObservableProperty] private string _currentMotivationQuote = string.Empty;

partial void OnSelectedTaskChanged(FocusTaskDto? value)
{
Expand Down Expand Up @@ -93,6 +97,10 @@ public void LoadRestoredSession(SessionHistoryDto restoredSession)
TimerDisplay = $"{RemainingSeconds / 60:D2}:{RemainingSeconds % 60:D2}";
TimerProgress = ((double)restoredSession.ActualSeconds / _totalSeconds) * 100;

CurrentMotivationQuote = "Hãy tiếp tục hoàn thành mục tiêu dang dở của bạn!";
_hasShownMidFocus = TimerProgress >= 50;
_hasShownPostFocus = TimerProgress >= 90;

_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
_timer.Tick += OnTimerTick;
_timer.Start();
Expand Down Expand Up @@ -135,6 +143,11 @@ private async Task StartSessionAsync()

IsSessionActive = true;
IsPaused = false;

_hasShownMidFocus = false;
_hasShownPostFocus = false;
var q = await _quoteUseCase.GetQuoteForEventAsync(QuoteEventTypeDto.PreFocus, "vi");
CurrentMotivationQuote = q?.Content ?? "Hãy tập trung hết sức cho mục tiêu của bạn!";

_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
_timer.Tick += OnTimerTick;
Expand All @@ -147,6 +160,20 @@ private async void OnTimerTick(object? sender, EventArgs e)
RemainingSeconds--;
TimerProgress = ((double)(_totalSeconds - RemainingSeconds) / _totalSeconds) * 100;
UpdateTimerDisplay();

if (TimerProgress >= 50 && !_hasShownMidFocus)
{
_hasShownMidFocus = true;
var q = await _quoteUseCase.GetQuoteForEventAsync(QuoteEventTypeDto.MidFocus, "vi");
if (q != null) CurrentMotivationQuote = q.Content;
}
else if (TimerProgress >= 90 && !_hasShownPostFocus)
{
_hasShownPostFocus = true;
var q = await _quoteUseCase.GetQuoteForEventAsync(QuoteEventTypeDto.PostFocus, "vi");
if (q != null) CurrentMotivationQuote = q.Content;
}

await _sessionUseCase.SyncSessionTimeAsync(_currentSession.Id, 1);
if (RemainingSeconds <= 0) await CompleteSessionAsync();
}
Expand Down
10 changes: 9 additions & 1 deletion src/DontBeLazy.WPF/Views/FocusSessionView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,16 @@
</StackPanel>
</Grid>

<!-- Motivation Quote (Pre, Mid, Post focus) -->
<TextBlock Text="{Binding CurrentMotivationQuote}"
FontSize="15" Foreground="#CCBBFF" Opacity="0.85"
TextWrapping="Wrap" TextAlignment="Center"
FontStyle="Italic"
MaxWidth="280" Margin="0,24,0,0"
Visibility="{Binding IsSessionActive, Converter={StaticResource BoolToVis}}" />

<!-- Controls (session active) -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,32,0,0"
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,24,0,0"
Visibility="{Binding IsSessionActive, Converter={StaticResource BoolToVis}}">
<!-- Pause button -->
<Button Command="{Binding PauseResumeCommand}"
Expand Down
Loading