Skip to content

Commit a4440ed

Browse files
committed
add human goal
1 parent 921adee commit a4440ed

11 files changed

Lines changed: 1755 additions & 101 deletions

AddTaskWindow.xaml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,34 +60,44 @@
6060
</Grid.RowDefinitions>
6161

6262
<TextBlock Grid.Row="0" Text="{local:Loc Key=AddTask_LabelDescription}" FontWeight="SemiBold"/>
63-
<TextBox Grid.Row="1" Name="TaskDescriptionTextBox" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Margin="0,5,0,10" MinHeight="60" BorderBrush="#CCCCCC" BorderThickness="1"/>
63+
<TextBox Grid.Row="1" Name="TaskDescriptionTextBox" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Margin="0,5,0,10" MinHeight="60" BorderBrush="#CCCCCC" BorderThickness="1" TextChanged="TaskDescriptionTextBox_TextChanged"/>
6464

65-
<Border Grid.Row="2" Name="ClarificationBorder" BorderBrush="OrangeRed" BorderThickness="1" Padding="5" Margin="0,0,0,10" Visibility="Collapsed">
65+
<Border Grid.Row="2" Name="SmartAssistantBorder" Background="#FFF6F2D8" BorderBrush="#E2C46E" BorderThickness="1" Padding="8" Margin="0,0,0,10" CornerRadius="6" Visibility="Collapsed">
66+
<StackPanel>
67+
<TextBlock Text="{local:Loc Key=AddTask_SmartAssistantTitle}" FontWeight="SemiBold" Margin="0,0,0,4"/>
68+
<TextBlock Name="SmartTaskSignalText" TextWrapping="Wrap" Margin="0,0,0,2"/>
69+
<TextBlock Name="SmartQuadrantSuggestionText" TextWrapping="Wrap" Margin="0,0,0,2"/>
70+
<TextBlock Name="SmartReminderSuggestionText" TextWrapping="Wrap" Margin="0,0,0,2"/>
71+
<TextBlock Name="SmartPreviewText" TextWrapping="Wrap" FontWeight="SemiBold"/>
72+
</StackPanel>
73+
</Border>
74+
75+
<Border Grid.Row="3" Name="ClarificationBorder" BorderBrush="OrangeRed" BorderThickness="1" Padding="5" Margin="0,0,0,10" Visibility="Collapsed">
6676
<StackPanel>
6777
<TextBlock Name="ClarificationPromptText" TextWrapping="Wrap" Foreground="OrangeRed" FontStyle="Italic" Margin="0,0,0,5" Visibility="Visible"/>
6878
<Button Name="ResetClarificationButton" Content="{local:Loc Key=AddTask_ButtonResetClarification}" HorizontalAlignment="Left" Margin="0,5,0,0" Visibility="Visible" Click="ResetClarificationButton_Click"/>
6979
</StackPanel>
7080
</Border>
7181

72-
<TextBlock Grid.Row="3" Text="{local:Loc Key=AddTask_LabelList}" FontWeight="SemiBold" Margin="0,0,0,5"/>
73-
<TextBlock Grid.Row="4" Name="LlmSuggestionText" TextWrapping="Wrap" FontStyle="Italic" Margin="0,0,0,5" Visibility="Collapsed"/>
82+
<TextBlock Grid.Row="4" Text="{local:Loc Key=AddTask_LabelList}" FontWeight="SemiBold" Margin="0,0,0,5"/>
83+
<TextBlock Grid.Row="5" Name="LlmSuggestionText" TextWrapping="Wrap" FontStyle="Italic" Margin="0,0,0,5" Visibility="Collapsed"/>
7484

75-
<CheckBox Grid.Row="5" Name="EnableReminderCheckBox" Content="{local:Loc Key=AddTask_EnableReminder}" Margin="0,5,0,5" IsChecked="False"/>
85+
<CheckBox Grid.Row="6" Name="EnableReminderCheckBox" Content="{local:Loc Key=AddTask_EnableReminder}" Margin="0,5,0,5" IsChecked="False" Checked="ReminderInput_Changed" Unchecked="ReminderInput_Changed"/>
7686

77-
<StackPanel Grid.Row="6" Name="ReminderControlsPanel" Orientation="Vertical" Margin="0,0,0,10" Visibility="{Binding IsChecked, ElementName=EnableReminderCheckBox, Converter={StaticResource BooleanToVisibilityConverter}}">
87+
<StackPanel Grid.Row="7" Name="ReminderControlsPanel" Orientation="Vertical" Margin="0,0,0,10" Visibility="{Binding IsChecked, ElementName=EnableReminderCheckBox, Converter={StaticResource BooleanToVisibilityConverter}}">
7888
<TextBlock Text="{local:Loc Key=AddTask_ReminderDate}" Margin="0,0,0,2"/>
79-
<DatePicker Name="ReminderDatePicker" Margin="0,0,0,5"/>
89+
<DatePicker Name="ReminderDatePicker" Margin="0,0,0,5" SelectedDateChanged="ReminderInput_Changed"/>
8090
<TextBlock Text="{local:Loc Key=AddTask_ReminderTime}" Margin="0,0,0,2"/>
8191
<StackPanel Orientation="Horizontal">
82-
<ComboBox Name="ReminderHourComboBox" Width="50" Margin="0,0,5,0"/>
92+
<ComboBox Name="ReminderHourComboBox" Width="50" Margin="0,0,5,0" SelectionChanged="ReminderInput_Changed"/>
8393
<TextBlock Text=":" VerticalAlignment="Center"/>
84-
<ComboBox Name="ReminderMinuteComboBox" Width="50" Margin="5,0,0,0"/>
94+
<ComboBox Name="ReminderMinuteComboBox" Width="50" Margin="5,0,0,0" SelectionChanged="ReminderInput_Changed"/>
8595
</StackPanel>
8696
</StackPanel>
8797

88-
<ComboBox Grid.Row="7" Name="ListSelectorComboBox" Margin="0,0,0,15"/>
98+
<ComboBox Grid.Row="8" Name="ListSelectorComboBox" Margin="0,0,0,15" SelectionChanged="ListSelectorComboBox_SelectionChanged"/>
8999

90-
<StackPanel Grid.Row="8" Orientation="Horizontal" HorizontalAlignment="Right">
100+
<StackPanel Grid.Row="9" Orientation="Horizontal" HorizontalAlignment="Right">
91101
<Button Name="AddTaskButton" Content="{local:Loc Key=AddTask_ButtonAdd}" Width="150" Margin="0,0,10,0" Click="AddTaskButton_Click">
92102
<Button.Resources>
93103
<Style TargetType="Border">

AddTaskWindow.xaml.cs

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using System.Windows;
45
using System.Windows.Input; // Required for MouseButtonEventArgs, MouseButtonState
6+
using System.Windows.Controls;
57
using System.Threading.Tasks; // For async operations
68

79
namespace TimeTask
810
{
911
// Removed duplicate namespace declaration
1012
public partial class AddTaskWindow : Window
1113
{
14+
public sealed class DraftSmartSuggestion
15+
{
16+
public string NormalizedDescription { get; set; }
17+
public double TaskLikelihoodScore { get; set; }
18+
public bool IsPotentialTask { get; set; }
19+
public string Importance { get; set; }
20+
public string Urgency { get; set; }
21+
public int SuggestedQuadrantIndex { get; set; } = -1;
22+
public DateTime? SuggestedReminderTime { get; set; }
23+
}
24+
1225
private LlmService _llmService;
1326
private DatabaseService _databaseService;
1427
private bool _isClarificationRound = false; // State for clarification
1528
private string _originalTaskDescription = string.Empty; // To store original task if clarification is needed
1629
private bool _isLlmConfigErrorNotified = false; // Flag to track if user has been notified of LLM config error
1730
private readonly IntentRecognizer _intentRecognizer = new IntentRecognizer();
31+
private bool _reminderEditedByUser;
32+
private bool _quadrantEditedByUser;
33+
private bool _isUpdatingReminderControls;
34+
private bool _isUpdatingQuadrantSelection;
35+
private bool _autoReminderApplied;
1836

1937
public string TaskDescription { get; private set; }
2038
public int SelectedListIndex { get; private set; } // 0-indexed
@@ -75,6 +93,8 @@ private void InitializeCombobox(int? defaultQuadrantIndex)
7593
ReminderDatePicker.SelectedDate = DateTime.Today;
7694
ReminderHourComboBox.SelectedIndex = 0; // Default to "00"
7795
ReminderMinuteComboBox.SelectedIndex = 0; // Default to "00"
96+
97+
RefreshSmartAssistant();
7898
}
7999

80100
/// <summary>
@@ -112,9 +132,12 @@ public void SetPreFilledTask(string description, string quadrant)
112132

113133
if (quadrantMap.TryGetValue(quadrant, out int index))
114134
{
135+
_quadrantEditedByUser = false;
115136
ListSelectorComboBox.SelectedIndex = index;
116137
}
117138
}
139+
140+
RefreshSmartAssistant();
118141
}
119142

120143
// Removed older synchronous AddTaskButton_Click method. The async version below is used.
@@ -408,6 +431,40 @@ private static bool ContainsDummy(string value)
408431
value.IndexOf("dummy response", StringComparison.OrdinalIgnoreCase) >= 0;
409432
}
410433

434+
public static DraftSmartSuggestion AnalyzeDraftInput(string rawText, DateTime now)
435+
{
436+
var recognizer = new IntentRecognizer();
437+
var parser = new VoiceReminderTimeParser();
438+
string normalized = string.IsNullOrWhiteSpace(rawText) ? string.Empty : rawText.Trim();
439+
string extracted = recognizer.ExtractTaskDescription(normalized);
440+
if (!string.IsNullOrWhiteSpace(extracted))
441+
{
442+
normalized = extracted.Trim();
443+
}
444+
445+
var suggestion = new DraftSmartSuggestion
446+
{
447+
NormalizedDescription = normalized,
448+
TaskLikelihoodScore = recognizer.ScoreTaskLikelihood(rawText),
449+
IsPotentialTask = recognizer.IsPotentialTask(rawText)
450+
};
451+
452+
if (!string.IsNullOrWhiteSpace(normalized))
453+
{
454+
var (importance, urgency) = recognizer.EstimatePriority(normalized);
455+
suggestion.Importance = importance;
456+
suggestion.Urgency = urgency;
457+
suggestion.SuggestedQuadrantIndex = GetIndexFromPriority(importance, urgency);
458+
}
459+
460+
if (parser.TryParse(rawText, now, out DateTime reminderTime))
461+
{
462+
suggestion.SuggestedReminderTime = reminderTime;
463+
}
464+
465+
return suggestion;
466+
}
467+
411468
private string NormalizeTaskText(string raw)
412469
{
413470
if (string.IsNullOrWhiteSpace(raw))
@@ -422,5 +479,152 @@ private string NormalizeTaskText(string raw)
422479

423480
return trimmed;
424481
}
482+
483+
private void TaskDescriptionTextBox_TextChanged(object sender, TextChangedEventArgs e)
484+
{
485+
RefreshSmartAssistant();
486+
}
487+
488+
private void ReminderInput_Changed(object sender, RoutedEventArgs e)
489+
{
490+
if (!_isUpdatingReminderControls)
491+
{
492+
_reminderEditedByUser = true;
493+
}
494+
495+
UpdatePreviewSummary();
496+
}
497+
498+
private void ListSelectorComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
499+
{
500+
if (!_isUpdatingQuadrantSelection)
501+
{
502+
_quadrantEditedByUser = true;
503+
}
504+
505+
UpdatePreviewSummary();
506+
}
507+
508+
private void RefreshSmartAssistant()
509+
{
510+
var suggestion = AnalyzeDraftInput(TaskDescriptionTextBox.Text, DateTime.Now);
511+
if (string.IsNullOrWhiteSpace(suggestion.NormalizedDescription))
512+
{
513+
SmartAssistantBorder.Visibility = Visibility.Collapsed;
514+
if (_autoReminderApplied && !_reminderEditedByUser)
515+
{
516+
ApplyReminderTime(null);
517+
_autoReminderApplied = false;
518+
}
519+
520+
return;
521+
}
522+
523+
SmartAssistantBorder.Visibility = Visibility.Visible;
524+
SmartTaskSignalText.Text = suggestion.IsPotentialTask
525+
? I18n.Tf("AddTask_SmartTaskSignalStrongFormat", Math.Round(suggestion.TaskLikelihoodScore * 100))
526+
: I18n.Tf("AddTask_SmartTaskSignalWeakFormat", Math.Round(suggestion.TaskLikelihoodScore * 100));
527+
528+
string quadrantLabel = suggestion.SuggestedQuadrantIndex >= 0 && suggestion.SuggestedQuadrantIndex < ListSelectorComboBox.Items.Count
529+
? ListSelectorComboBox.Items[suggestion.SuggestedQuadrantIndex] as string
530+
: I18n.T("AddTask_SmartQuadrantUnavailable");
531+
SmartQuadrantSuggestionText.Text = I18n.Tf("AddTask_SmartQuadrantFormat", quadrantLabel);
532+
533+
if (suggestion.SuggestedReminderTime.HasValue)
534+
{
535+
SmartReminderSuggestionText.Text = I18n.Tf(
536+
"AddTask_SmartReminderDetectedFormat",
537+
suggestion.SuggestedReminderTime.Value.ToString("yyyy-MM-dd HH:mm", I18n.CurrentCulture));
538+
539+
if (!_reminderEditedByUser)
540+
{
541+
ApplyReminderTime(suggestion.SuggestedReminderTime);
542+
_autoReminderApplied = true;
543+
}
544+
}
545+
else
546+
{
547+
SmartReminderSuggestionText.Text = I18n.T("AddTask_SmartReminderNone");
548+
if (_autoReminderApplied && !_reminderEditedByUser)
549+
{
550+
ApplyReminderTime(null);
551+
_autoReminderApplied = false;
552+
}
553+
}
554+
555+
if (suggestion.SuggestedQuadrantIndex >= 0 && !_quadrantEditedByUser)
556+
{
557+
_isUpdatingQuadrantSelection = true;
558+
try
559+
{
560+
ListSelectorComboBox.SelectedIndex = suggestion.SuggestedQuadrantIndex;
561+
}
562+
finally
563+
{
564+
_isUpdatingQuadrantSelection = false;
565+
}
566+
}
567+
568+
UpdatePreviewSummary();
569+
}
570+
571+
private void ApplyReminderTime(DateTime? reminderTime)
572+
{
573+
_isUpdatingReminderControls = true;
574+
try
575+
{
576+
if (reminderTime.HasValue)
577+
{
578+
EnableReminderCheckBox.IsChecked = true;
579+
ReminderDatePicker.SelectedDate = reminderTime.Value.Date;
580+
ReminderHourComboBox.SelectedItem = reminderTime.Value.Hour.ToString("D2", CultureInfo.InvariantCulture);
581+
ReminderMinuteComboBox.SelectedItem = reminderTime.Value.Minute.ToString("D2", CultureInfo.InvariantCulture);
582+
}
583+
else
584+
{
585+
EnableReminderCheckBox.IsChecked = false;
586+
ReminderDatePicker.SelectedDate = DateTime.Today;
587+
ReminderHourComboBox.SelectedIndex = 0;
588+
ReminderMinuteComboBox.SelectedIndex = 0;
589+
}
590+
}
591+
finally
592+
{
593+
_isUpdatingReminderControls = false;
594+
}
595+
}
596+
597+
private void UpdatePreviewSummary()
598+
{
599+
string quadrantText = ListSelectorComboBox.SelectedItem as string ?? I18n.T("AddTask_SmartQuadrantUnavailable");
600+
DateTime? selectedReminder = GetReminderTimeFromControls();
601+
602+
SmartPreviewText.Text = selectedReminder.HasValue
603+
? I18n.Tf("AddTask_SmartPreviewFormat", quadrantText, selectedReminder.Value.ToString("yyyy-MM-dd HH:mm", I18n.CurrentCulture))
604+
: I18n.Tf("AddTask_SmartPreviewNoReminderFormat", quadrantText);
605+
}
606+
607+
private DateTime? GetReminderTimeFromControls()
608+
{
609+
if (EnableReminderCheckBox.IsChecked != true || !ReminderDatePicker.SelectedDate.HasValue)
610+
{
611+
return null;
612+
}
613+
614+
int hour = 0;
615+
int minute = 0;
616+
if (ReminderHourComboBox.SelectedItem != null)
617+
{
618+
int.TryParse(ReminderHourComboBox.SelectedItem.ToString(), out hour);
619+
}
620+
621+
if (ReminderMinuteComboBox.SelectedItem != null)
622+
{
623+
int.TryParse(ReminderMinuteComboBox.SelectedItem.ToString(), out minute);
624+
}
625+
626+
DateTime date = ReminderDatePicker.SelectedDate.Value;
627+
return new DateTime(date.Year, date.Month, date.Day, hour, minute, 0);
628+
}
425629
}
426630
} // Closing brace for namespace TimeTask

0 commit comments

Comments
 (0)