forked from jenius-apps/ambie
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fixed automation name not updating on state change * Added sleep timer
- Loading branch information
Showing
9 changed files
with
322 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<UserControl | ||
x:Class="AmbientSounds.Controls.SleepTimerControl" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:local="using:AmbientSounds.Controls" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls" | ||
d:DesignHeight="300" | ||
d:DesignWidth="400" | ||
mc:Ignorable="d"> | ||
|
||
<StackPanel Orientation="Horizontal"> | ||
<Button | ||
Width="40" | ||
Height="40" | ||
AutomationProperties.Name="Click here to set up a sleep timer, where the sound will pause after the selected time." | ||
Background="Transparent" | ||
CornerRadius="20" | ||
ToolTipService.ToolTip="Click here to set up a sleep timer, where the sound will pause after the selected time."> | ||
<Grid> | ||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" /> | ||
</Grid> | ||
<Button.Flyout> | ||
<muxc:CommandBarFlyout Placement="BottomEdgeAlignedLeft"> | ||
<muxc:CommandBarFlyout.PrimaryCommands> | ||
<AppBarButton | ||
AutomationProperties.Name="Continue timer" | ||
Command="{x:Bind ViewModel.TimerPlayCommand}" | ||
Icon="Play" /> | ||
<AppBarButton | ||
AutomationProperties.Name="Pause timer" | ||
Command="{x:Bind ViewModel.TimerPauseCommand}" | ||
Icon="Pause" /> | ||
<AppBarButton | ||
AutomationProperties.Name="Stop timer and clear time" | ||
Command="{x:Bind ViewModel.TimerStopCommand}" | ||
Icon="Stop" /> | ||
</muxc:CommandBarFlyout.PrimaryCommands> | ||
<muxc:CommandBarFlyout.SecondaryCommands> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.TimerStartCommand}" | ||
Icon="Clock" | ||
Label="5 minutes"> | ||
<AppBarButton.CommandParameter> | ||
<x:Int32>5</x:Int32> | ||
</AppBarButton.CommandParameter> | ||
</AppBarButton> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.TimerStartCommand}" | ||
Icon="Clock" | ||
Label="10 minutes"> | ||
<AppBarButton.CommandParameter> | ||
<x:Int32>10</x:Int32> | ||
</AppBarButton.CommandParameter> | ||
</AppBarButton> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.TimerStartCommand}" | ||
Icon="Clock" | ||
Label="15 minutes"> | ||
<AppBarButton.CommandParameter> | ||
<x:Int32>15</x:Int32> | ||
</AppBarButton.CommandParameter> | ||
</AppBarButton> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.TimerStartCommand}" | ||
Icon="Clock" | ||
Label="30 minutes"> | ||
<AppBarButton.CommandParameter> | ||
<x:Int32>30</x:Int32> | ||
</AppBarButton.CommandParameter> | ||
</AppBarButton> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.TimerStartCommand}" | ||
Icon="Clock" | ||
Label="60 minutes"> | ||
<AppBarButton.CommandParameter> | ||
<x:Int32>60</x:Int32> | ||
</AppBarButton.CommandParameter> | ||
</AppBarButton> | ||
</muxc:CommandBarFlyout.SecondaryCommands> | ||
</muxc:CommandBarFlyout> | ||
</Button.Flyout> | ||
</Button> | ||
<TextBlock | ||
Margin="12,0,0,0" | ||
VerticalAlignment="Center" | ||
Text="{x:Bind ViewModel.TimeLeft, Mode=OneWay}" | ||
Visibility="{x:Bind ViewModel.CountdownVisible, Mode=OneWay}" /> | ||
</StackPanel> | ||
</UserControl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using AmbientSounds.ViewModels; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Windows.UI.Xaml.Controls; | ||
|
||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 | ||
|
||
namespace AmbientSounds.Controls | ||
{ | ||
public sealed partial class SleepTimerControl : UserControl | ||
{ | ||
public SleepTimerControl() | ||
{ | ||
this.InitializeComponent(); | ||
this.DataContext = App.Services.GetRequiredService<SleepTimerViewModel>(); | ||
} | ||
|
||
public SleepTimerViewModel ViewModel => (SleepTimerViewModel)this.DataContext; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System; | ||
using System.Timers; | ||
using Windows.System; | ||
|
||
namespace AmbientSounds.Services | ||
{ | ||
/// <summary> | ||
/// Class for handling a timer countdown. | ||
/// </summary> | ||
public class TimerService : ITimerService | ||
{ | ||
/// <inheritdoc/> | ||
public event EventHandler<int> IntervalElapsed; | ||
|
||
private readonly Timer _timer; | ||
private readonly DispatcherQueue _dispatcherQueue; | ||
|
||
public TimerService() | ||
{ | ||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread(); | ||
_timer = new Timer(); | ||
_timer.Elapsed += TimerIntervalElapsed; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public int Interval | ||
{ | ||
get => (int)_timer.Interval; | ||
set => _timer.Interval = value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public TimeSpan Remaining { get; set; } | ||
|
||
/// <inheritdoc/> | ||
public void Start() | ||
{ | ||
_timer.Start(); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void Stop() | ||
{ | ||
_timer.Stop(); | ||
} | ||
|
||
private void TimerIntervalElapsed(object sender, object e) | ||
{ | ||
Remaining -= new TimeSpan(0, 0, 0, 0, Interval); | ||
_dispatcherQueue.TryEnqueue(() => IntervalElapsed?.Invoke(sender, Interval)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System; | ||
|
||
namespace AmbientSounds.Services | ||
{ | ||
/// <summary> | ||
/// Interface for a timer. | ||
/// </summary> | ||
public interface ITimerService | ||
{ | ||
/// <summary> | ||
/// Triggered when the interval elapses. | ||
/// Interval is milliseconds. | ||
/// </summary> | ||
event EventHandler<int> IntervalElapsed; | ||
|
||
/// <summary> | ||
/// Interval in milliseconds. | ||
/// </summary> | ||
int Interval { get; set; } | ||
|
||
/// <summary> | ||
/// The time remaining. | ||
/// </summary> | ||
TimeSpan Remaining { get; set; } | ||
|
||
/// <summary> | ||
/// Start the timer. | ||
/// </summary> | ||
void Start(); | ||
|
||
/// <summary> | ||
/// Stop the timer. | ||
/// </summary> | ||
void Stop(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
using AmbientSounds.Services; | ||
using Microsoft.Toolkit.Diagnostics; | ||
using Microsoft.Toolkit.Mvvm.ComponentModel; | ||
using Microsoft.Toolkit.Mvvm.Input; | ||
using System; | ||
|
||
namespace AmbientSounds.ViewModels | ||
{ | ||
public class SleepTimerViewModel : ObservableObject | ||
{ | ||
private const int DefaultTimerInterval = 1000; | ||
private readonly IMediaPlayerService _player; | ||
private readonly ITimerService _timer; | ||
|
||
public SleepTimerViewModel( | ||
IMediaPlayerService player, | ||
ITimerService timer) | ||
{ | ||
Guard.IsNotNull(player, nameof(player)); | ||
Guard.IsNotNull(timer, nameof(timer)); | ||
|
||
_player = player; | ||
_timer = timer; | ||
_timer.Interval = DefaultTimerInterval; | ||
_timer.IntervalElapsed += TimerElapsed; | ||
|
||
TimerStartCommand = new RelayCommand<int>(StartTimer); | ||
TimerPlayCommand = new RelayCommand(PlayTimer); | ||
TimerPauseCommand = new RelayCommand(PauseTimer); | ||
TimerStopCommand = new RelayCommand(StopTimer); | ||
} | ||
|
||
/// <summary> | ||
/// Starts the timer with the specified remainder time. | ||
/// </summary> | ||
public IRelayCommand<int> TimerStartCommand { get; } | ||
|
||
/// <summary> | ||
/// Plays the timer if it were paused. | ||
/// </summary> | ||
public IRelayCommand TimerPlayCommand { get; } | ||
|
||
/// <summary> | ||
/// Pauses the timer. | ||
/// </summary> | ||
public IRelayCommand TimerPauseCommand { get; } | ||
|
||
/// <summary> | ||
/// Stops the timer and clears the countdown. | ||
/// </summary> | ||
public IRelayCommand TimerStopCommand { get; } | ||
|
||
/// <summary> | ||
/// Determines if the sleep timer's countdown | ||
/// is visible. | ||
/// </summary> | ||
public bool CountdownVisible | ||
{ | ||
get => _countdownVisible; | ||
set => SetProperty(ref _countdownVisible, value); | ||
} | ||
private bool _countdownVisible; | ||
|
||
/// <summary> | ||
/// String representation of time remaining. | ||
/// E.g. 0:59:12 for 59 minutes and 12 seconds left. | ||
/// </summary> | ||
public string TimeLeft => _timer.Remaining.ToString("g"); | ||
|
||
private void StartTimer(int minutes) | ||
{ | ||
_timer.Remaining = new TimeSpan(0, minutes, 0); | ||
OnPropertyChanged(nameof(TimeLeft)); | ||
CountdownVisible = true; | ||
_timer.Start(); | ||
} | ||
|
||
private void PlayTimer() | ||
{ | ||
if (_timer.Remaining > new TimeSpan(0)) | ||
{ | ||
_timer.Start(); | ||
} | ||
} | ||
|
||
private void PauseTimer() | ||
{ | ||
_timer.Stop(); | ||
} | ||
|
||
private void StopTimer() | ||
{ | ||
_timer.Stop(); | ||
_timer.Remaining = new TimeSpan(0); | ||
CountdownVisible = false; | ||
} | ||
|
||
private void TimerElapsed(object sender, int intervalInMs) | ||
{ | ||
OnPropertyChanged(nameof(TimeLeft)); | ||
if (_timer.Remaining < new TimeSpan(0, 0, 1)) | ||
{ | ||
StopTimer(); | ||
_player.Pause(); | ||
} | ||
} | ||
} | ||
} |