Skip to content

Commit 2854947

Browse files
committed
Added the ability to specify a total duration for a session
1 parent 8d66c7b commit 2854947

File tree

5 files changed

+95
-11
lines changed

5 files changed

+95
-11
lines changed

Source/VisualPairCoding/VisualPairCoding.AvaloniaUI/EnterNamesWindow.axaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@
6262
<Separator Height="10" />
6363

6464
<Grid ColumnDefinitions="Auto,Auto, 25,Auto" RowDefinitions="Auto,Auto,Auto,Auto" Margin="4">
65-
<TextBlock Padding="10" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">Number of minutes per turn</TextBlock>
66-
<NumericUpDown x:Name="minutesPerTurn" Maximum="30" Minimum="1" Value="7" Width="100" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"/>
65+
<CheckBox x:Name="totalDurationCheckBox" Padding="5" Grid.Row="1" Grid.Column="0" Content="Total Duration" IsChecked="False" Checked="TotalDurationCheckBoxChecked" Unchecked="TotalDurationCheckBoxUnchecked"/>
66+
<TextBlock x:Name="minutesTextBlockText" Padding="1" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" IsVisible="True">Minutes per turn</TextBlock>
67+
<NumericUpDown x:Name="minutesPerTurn" Maximum="30" Minimum="1" Value="7" Width="100" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" IsVisible="True"/>
68+
<TimePicker x:Name="timePicker" Grid.Row="1" Grid.Column="1" IsVisible="False"/>
6769
<Button Click="RandomizeParticipants" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center">Randomize Participants</Button>
6870
</Grid>
6971

Source/VisualPairCoding/VisualPairCoding.AvaloniaUI/EnterNamesWindow.axaml.cs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Avalonia;
12
using Avalonia.Controls;
23
using Avalonia.Interactivity;
34
using System;
@@ -12,6 +13,7 @@ namespace VisualPairCoding.AvaloniaUI
1213
public partial class EnterNamesForm : Window
1314
{
1415
private bool _autostart = false;
16+
private bool isTotalDurationActivated = false;
1517
public EnterNamesForm()
1618
{
1719
InitializeComponent();
@@ -37,6 +39,44 @@ private MenuItem GetRecentMenuItem()
3739
return this.FindControl<MenuItem>("recentMenuItem");
3840
}
3941

42+
43+
44+
private TimeSpan GetSessionTotalDuration()
45+
{
46+
if (timePicker.SelectedTime.HasValue)
47+
{
48+
return timePicker.SelectedTime.Value;
49+
}
50+
51+
return new TimeSpan(0, 0, 0);
52+
}
53+
54+
55+
private void TotalDurationCheckBoxChecked(object sender, RoutedEventArgs e)
56+
{
57+
var checkbox = (CheckBox)sender;
58+
59+
if (checkbox.IsChecked == true)
60+
{
61+
timePicker.IsVisible = true;
62+
isTotalDurationActivated = true;
63+
}
64+
65+
}
66+
67+
68+
private void TotalDurationCheckBoxUnchecked(object sender, RoutedEventArgs e)
69+
{
70+
var checkbox = (CheckBox)sender;
71+
72+
if (checkbox.IsChecked == false)
73+
{
74+
timePicker.IsVisible = false;
75+
isTotalDurationActivated = false;
76+
}
77+
78+
}
79+
4080
private async Task<bool> AutoUpdate()
4181
{
4282
var updater = new AutoUpdater(
@@ -68,6 +108,7 @@ private void OnClosed(object? sender, EventArgs e)
68108
);
69109
}
70110

111+
71112
private void OnMenuItemClicked(object? sender, RoutedEventArgs e)
72113
{
73114
MenuItem clickedMenuItem = (MenuItem)e.Source!;
@@ -110,8 +151,8 @@ public void CloseWindow(object? sender, RoutedEventArgs args)
110151
public async void StartForm(object? sender, RoutedEventArgs args)
111152
{
112153
var participants = GetParticipants();
113-
var session = new PairCodingSession(participants, (int)minutesPerTurn.Value);
114-
154+
var totalDuration = GetSessionTotalDuration();
155+
var session = new PairCodingSession(participants, (int)minutesPerTurn.Value, GetSessionTotalDuration());
115156
var validationMessage = session.Validate();
116157

117158
if (!string.IsNullOrWhiteSpace(validationMessage))
@@ -125,7 +166,7 @@ public async void StartForm(object? sender, RoutedEventArgs args)
125166

126167
try
127168
{
128-
RunSessionForm sessionForm = new(session);
169+
RunSessionForm sessionForm = new(session, isTotalDurationActivated);
129170
sessionForm.Show();
130171
// Let the session window start in about the location we have right now on the screen
131172
sessionForm.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top;

Source/VisualPairCoding/VisualPairCoding.AvaloniaUI/RunSessionForm.axaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,24 @@
1414
</Grid.ColumnDefinitions>
1515

1616
<StackPanel Grid.Column="0" Margin="10">
17+
1718
<Label FontWeight="Medium" FontStyle="Italic" Height="25" Content="Driver" Foreground="#9c9c9c" />
1819
<StackPanel Orientation="Horizontal" Spacing="5">
1920
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="3" Height="20" x:Name="activeParticipnat" Text="Label Name 1"/>
2021
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
2122
<TextBlock Height="20" x:Name="remainingTimeLabel" Text="Remaining" Margin="3" HorizontalAlignment="Right"/>
2223
</StackPanel>
2324
</StackPanel>
25+
26+
2427
<Label FontWeight="Medium" FontStyle="Italic" Height="25" Content="Rec. Navigator" Foreground="#9c9c9c"/>
25-
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="3" Height="35" x:Name="recommendedNavigator" Text="Label Name 2" Foreground="#9c9c9c"/>
28+
<StackPanel Orientation="Horizontal" Spacing="5">
29+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="3" Height="20" x:Name="recommendedNavigator" Text="Label Name 2" Foreground="#9c9c9c"/>
30+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
31+
<TextBlock Height="20" x:Name="totalDurationRemaining" Text="" Margin="3" HorizontalAlignment="Right"/>
32+
</StackPanel>
33+
</StackPanel>
34+
2635
</StackPanel>
2736

2837
<StackPanel Grid.Column="1" HorizontalAlignment="Right" Margin="10">

Source/VisualPairCoding/VisualPairCoding.AvaloniaUI/RunSessionForm.axaml.cs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,29 @@ public partial class RunSessionForm : Window
1414
{
1515
private readonly PairCodingSession _pairCodingSession;
1616
private TimeSpan _currentTime = TimeSpan.Zero;
17+
private TimeSpan _totalDuration;
1718
private int _currentParticipant = -1;
1819
private readonly Random random = new();
1920
private readonly DispatcherTimer timer;
2021
private readonly bool _explicitlyConfirmTurnChange = true;
21-
22+
private bool _totalDurationActivated;
2223
public RunSessionForm()
2324
{
2425
InitializeComponent();
2526
}
2627

27-
public RunSessionForm(PairCodingSession pairCodingSession)
28+
public RunSessionForm(PairCodingSession pairCodingSession, bool isTotalDurationActivated)
2829
{
2930
InitializeComponent();
3031
timer = new DispatcherTimer
3132
{
3233
Interval = TimeSpan.FromSeconds(1)
3334
};
3435
timer.Tick += Timer_Tick;
36+
_totalDurationActivated = isTotalDurationActivated;
3537
timer.IsEnabled = true;
3638
_pairCodingSession = pairCodingSession;
39+
_totalDuration = new TimeSpan(_pairCodingSession.TotalDuration.Hours, _pairCodingSession.TotalDuration.Minutes, 0);
3740
ExtendClientAreaToDecorationsHint = true;
3841
ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.NoChrome;
3942
ExtendClientAreaTitleBarHeightHint = -1;
@@ -89,18 +92,44 @@ private void CloseForm(object sender, RoutedEventArgs args)
8992
Close();
9093
}
9194

92-
private void Timer_Tick(object? sender, EventArgs e)
95+
private async void Timer_Tick(object? sender, EventArgs e)
9396
{
97+
if (_totalDuration <= TimeSpan.Zero && _totalDurationActivated)
98+
{
99+
timer.IsEnabled = false;
100+
var totalForm = new NewTurnForm(
101+
"Total Duration Exceeded!",
102+
_explicitlyConfirmTurnChange
103+
);
104+
105+
var tcs = new TaskCompletionSource<object>();
106+
totalForm.Closed += (s, e) => tcs.SetResult(null!);
107+
108+
totalForm.Show();
109+
totalForm.Topmost = true;
110+
await tcs.Task;
111+
Close();
112+
return;
113+
}
114+
94115
if (_currentTime <= TimeSpan.Zero)
95116
{
96117
ChooseAnotherPairAndStartNewTurn();
97118
}
119+
120+
if (_totalDurationActivated)
121+
{
122+
_totalDuration = _totalDuration.Subtract(TimeSpan.FromSeconds(1));
123+
totalDurationRemaining.Text = $"Total: {_totalDuration}";
124+
}
125+
98126
_currentTime = _currentTime.Subtract(TimeSpan.FromSeconds(1));
99127
remainingTimeLabel.Text = _currentTime.ToString();
100128
}
101129

102130
private async void ChooseAnotherPairAndStartNewTurn()
103131
{
132+
104133
timer.Stop();
105134

106135
_currentTime = new TimeSpan(0, _pairCodingSession.MinutesPerTurn, 0);
@@ -159,7 +188,7 @@ private void SkipCurrentDriverButton_Click(object? sender, RoutedEventArgs args)
159188
ChooseAnotherPairAndStartNewTurn();
160189
activeParticipnat.Text = _pairCodingSession.Participants[_currentParticipant];
161190

162-
remainingTimeLabel.Text = _currentTime.ToString();
191+
remainingTimeLabel.Text = _currentTime.ToString();
163192

164193
}
165194

Source/VisualPairCoding/VisualPairCoding.BL/PairCodingSession.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ public class PairCodingSession
66

77
public int MinutesPerTurn { get; }
88

9-
public PairCodingSession(string[] participants, int minutesPerTurn)
9+
public TimeSpan TotalDuration { get; }
10+
11+
public PairCodingSession(string[] participants, int minutesPerTurn, TimeSpan totalDuration)
1012
{
1113
Participants = participants;
1214
MinutesPerTurn = minutesPerTurn;
15+
TotalDuration = totalDuration;
1316
}
1417

1518
public string? Validate()

0 commit comments

Comments
 (0)