mirror of
https://github.com/usatiuk/PomoTime.git
synced 2025-10-29 00:47:48 +01:00
notifications that actually work
This commit is contained in:
@@ -42,7 +42,7 @@
|
|||||||
x:Name="MinutesText"
|
x:Name="MinutesText"
|
||||||
FontSize="60"
|
FontSize="60"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Text="{x:Bind runningState.MinutesLeft, Converter={StaticResource FormatStringConverter}, Mode=OneWay, ConverterParameter='00'}" />
|
Text="{x:Bind MainViewRunningState.MinutesLeft, Converter={StaticResource FormatStringConverter}, Mode=OneWay, ConverterParameter='00'}" />
|
||||||
<Run
|
<Run
|
||||||
x:Name="Separator"
|
x:Name="Separator"
|
||||||
FontSize="30"
|
FontSize="30"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
x:Name="SecondsText"
|
x:Name="SecondsText"
|
||||||
FontSize="30"
|
FontSize="30"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Text="{x:Bind runningState.SecondsLeft, Converter={StaticResource FormatStringConverter}, Mode=OneWay, ConverterParameter='00'}" />
|
Text="{x:Bind MainViewRunningState.SecondsLeft, Converter={StaticResource FormatStringConverter}, Mode=OneWay, ConverterParameter='00'}" />
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</RichTextBlock>
|
</RichTextBlock>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
FontSize="30"
|
FontSize="30"
|
||||||
FontWeight="Light"
|
FontWeight="Light"
|
||||||
Text="{x:Bind runningState.CurrentPeriod, Converter={StaticResource PeriodToStringConverter}, Mode=OneWay}" />
|
Text="{x:Bind MainViewRunningState.CurrentPeriod, Converter={StaticResource PeriodToStringConverter}, Mode=OneWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="0" Grid.Column="1">
|
<Grid Grid.Row="0" Grid.Column="1">
|
||||||
<Grid>
|
<Grid>
|
||||||
@@ -123,13 +123,13 @@
|
|||||||
Click="PlayButton_Click"
|
Click="PlayButton_Click"
|
||||||
Icon="Play"
|
Icon="Play"
|
||||||
Label="Start"
|
Label="Start"
|
||||||
Visibility="{x:Bind runningState.IsRunning, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay, ConverterParameter=True}" />
|
Visibility="{x:Bind MainViewRunningState.IsRunning, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay, ConverterParameter=True}" />
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="PauseButton"
|
x:Name="PauseButton"
|
||||||
Click="PauseButton_Click"
|
Click="PauseButton_Click"
|
||||||
Icon="Pause"
|
Icon="Pause"
|
||||||
Label="Pause"
|
Label="Pause"
|
||||||
Visibility="{x:Bind runningState.IsRunning, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
Visibility="{x:Bind MainViewRunningState.IsRunning, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="ResetButton"
|
x:Name="ResetButton"
|
||||||
Click="ResetButton_Click"
|
Click="ResetButton_Click"
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ using Windows.UI.Xaml.Data;
|
|||||||
using Windows.UI.Xaml.Input;
|
using Windows.UI.Xaml.Input;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.System.Threading;
|
using Windows.System.Threading;
|
||||||
using Windows.UI.Core;
|
using Windows.UI.Core;
|
||||||
using Microsoft.Toolkit.Uwp.Notifications;
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
using Windows.UI.Notifications;
|
|
||||||
|
|
||||||
|
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||||
@@ -30,11 +30,12 @@ namespace PomoTime
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class MainPage : Page
|
public sealed partial class MainPage : Page
|
||||||
{
|
{
|
||||||
public RunningState runningState = new RunningState();
|
public RunningState MainViewRunningState = new RunningState();
|
||||||
private const int DefaultBreakMinutes = 5;
|
private const int DefaultBreakMinutes = 5;
|
||||||
private const int DefaultWorkMinutes = 25;
|
private const int DefaultWorkMinutes = 25;
|
||||||
private const int DefaultLongBreakMinutes = 15;
|
private const int DefaultLongBreakMinutes = 15;
|
||||||
|
|
||||||
|
private DateTime SuspendTime;
|
||||||
private int _work_minutes;
|
private int _work_minutes;
|
||||||
private int BreakMinutes { get; set; }
|
private int BreakMinutes { get; set; }
|
||||||
private int WorkMinutes
|
private int WorkMinutes
|
||||||
@@ -42,9 +43,9 @@ namespace PomoTime
|
|||||||
get { return _work_minutes; }
|
get { return _work_minutes; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!runningState.IsRunning && runningState.CurrentPeriod == Period.Work)
|
if (!MainViewRunningState.IsRunning && MainViewRunningState.CurrentPeriod == Period.Work)
|
||||||
{
|
{
|
||||||
runningState.MinutesLeft = value;
|
MainViewRunningState.MinutesLeft = value;
|
||||||
}
|
}
|
||||||
_work_minutes = value;
|
_work_minutes = value;
|
||||||
}
|
}
|
||||||
@@ -64,6 +65,7 @@ namespace PomoTime
|
|||||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||||
|
|
||||||
Application.Current.Suspending += OnSuspending;
|
Application.Current.Suspending += OnSuspending;
|
||||||
|
Application.Current.Resuming += OnResuming;
|
||||||
this.Loaded += MainPageLoaded;
|
this.Loaded += MainPageLoaded;
|
||||||
|
|
||||||
ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
|
ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
|
||||||
@@ -102,79 +104,85 @@ namespace PomoTime
|
|||||||
BreakMinutes = DefaultBreakMinutes;
|
BreakMinutes = DefaultBreakMinutes;
|
||||||
LongBreakMinutes = DefaultLongBreakMinutes;
|
LongBreakMinutes = DefaultLongBreakMinutes;
|
||||||
}
|
}
|
||||||
runningState.MinutesLeft = WorkMinutes;
|
MainViewRunningState.MinutesLeft = WorkMinutes;
|
||||||
runningState.SecondsLeft = 0;
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_Tick()
|
void timer_Tick()
|
||||||
{
|
{
|
||||||
if (!runningState.IsRunning)
|
if (!MainViewRunningState.IsRunning)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (runningState.SecondsLeft == 0)
|
if (MainViewRunningState.SecondsLeft == 0)
|
||||||
{
|
{
|
||||||
runningState.SecondsLeft = 59;
|
MainViewRunningState.SecondsLeft = 59;
|
||||||
if (runningState.MinutesLeft == 0)
|
if (MainViewRunningState.MinutesLeft == 0)
|
||||||
{
|
{
|
||||||
switch (runningState.CurrentPeriod)
|
switch (MainViewRunningState.CurrentPeriod)
|
||||||
{
|
{
|
||||||
case Period.Work:
|
case Period.Work:
|
||||||
if (runningState.PreviousShortBreaks != 4)
|
if (MainViewRunningState.PreviousShortBreaks != 4)
|
||||||
{
|
{
|
||||||
runningState.CurrentPeriod = Period.ShortBreak;
|
MainViewRunningState.CurrentPeriod = Period.ShortBreak;
|
||||||
runningState.MinutesLeft = BreakMinutes;
|
MainViewRunningState.MinutesLeft = BreakMinutes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runningState.CurrentPeriod = Period.LongBreak;
|
MainViewRunningState.CurrentPeriod = Period.LongBreak;
|
||||||
runningState.MinutesLeft = LongBreakMinutes;
|
MainViewRunningState.MinutesLeft = LongBreakMinutes;
|
||||||
}
|
}
|
||||||
runningState.SecondsLeft = 0;
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Period.ShortBreak:
|
case Period.ShortBreak:
|
||||||
runningState.CurrentPeriod = Period.Work;
|
MainViewRunningState.CurrentPeriod = Period.Work;
|
||||||
runningState.PreviousShortBreaks += 1;
|
MainViewRunningState.PreviousShortBreaks += 1;
|
||||||
runningState.MinutesLeft = WorkMinutes;
|
MainViewRunningState.MinutesLeft = WorkMinutes;
|
||||||
runningState.SecondsLeft = 0;
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
break;
|
break;
|
||||||
case Period.LongBreak:
|
case Period.LongBreak:
|
||||||
runningState.CurrentPeriod = Period.Work;
|
MainViewRunningState.CurrentPeriod = Period.Work;
|
||||||
runningState.PreviousShortBreaks = 0;
|
MainViewRunningState.PreviousShortBreaks = 0;
|
||||||
runningState.MinutesLeft = WorkMinutes;
|
MainViewRunningState.MinutesLeft = WorkMinutes;
|
||||||
runningState.SecondsLeft = 0;
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
SendToast();
|
SchedulePeriodOverNotification();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runningState.MinutesLeft--;
|
MainViewRunningState.MinutesLeft--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (MainViewRunningState.SecondsLeft == 1 && MainViewRunningState.MinutesLeft == 0)
|
||||||
|
{
|
||||||
|
MainViewRunningState.IsRunning = false;
|
||||||
|
MainViewRunningState.SecondsLeft--;
|
||||||
|
SchedulePeriodOverNotification();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runningState.SecondsLeft--;
|
MainViewRunningState.SecondsLeft--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendToast()
|
void SchedulePeriodOverNotification()
|
||||||
{
|
{
|
||||||
string header;
|
string header;
|
||||||
switch (runningState.CurrentPeriod)
|
switch (MainViewRunningState.CurrentPeriod)
|
||||||
{
|
{
|
||||||
case Period.LongBreak:
|
case Period.LongBreak:
|
||||||
header = "Long break time!";
|
header = "Long break time over!";
|
||||||
break;
|
break;
|
||||||
case Period.ShortBreak:
|
case Period.ShortBreak:
|
||||||
header = "Short break time!";
|
header = "Short break time over!";
|
||||||
break;
|
break;
|
||||||
case Period.Work:
|
case Period.Work:
|
||||||
header = "Work time!";
|
header = "Work time over!";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
@@ -199,50 +207,69 @@ namespace PomoTime
|
|||||||
Visual = visual,
|
Visual = visual,
|
||||||
};
|
};
|
||||||
|
|
||||||
var toast = new ToastNotification(toastContent.GetXml());
|
TimeSpan WaitTime = new TimeSpan(0, MainViewRunningState.MinutesLeft, MainViewRunningState.SecondsLeft);
|
||||||
toast.ExpirationTime = DateTime.Now.AddMinutes(runningState.MinutesLeft);
|
var toast = new Windows.UI.Notifications.ScheduledToastNotification(toastContent.GetXml(), DateTime.Now + WaitTime);
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
Windows.UI.Notifications.ToastNotificationManager.CreateToastNotifier().AddToSchedule(toast);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearScheduledNotifications()
|
||||||
|
{
|
||||||
|
ToastNotifier notifier = ToastNotificationManager.CreateToastNotifier();
|
||||||
|
IReadOnlyList<ScheduledToastNotification> scheduledToasts = notifier.GetScheduledToastNotifications();
|
||||||
|
foreach (ScheduledToastNotification n in scheduledToasts)
|
||||||
|
{
|
||||||
|
notifier.RemoveFromSchedule(n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void PlayButton_Click(object sender, RoutedEventArgs e)
|
private void PlayButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.IsRunning = true;
|
MainViewRunningState.IsRunning = true;
|
||||||
|
|
||||||
|
if(MainViewRunningState.MinutesLeft != 0 || MainViewRunningState.SecondsLeft != 0)
|
||||||
|
{
|
||||||
|
SchedulePeriodOverNotification();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PauseButton_Click(object sender, RoutedEventArgs e)
|
private void PauseButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.IsRunning = false;
|
MainViewRunningState.IsRunning = false;
|
||||||
|
|
||||||
|
ClearScheduledNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetButton_Click(object sender, RoutedEventArgs e)
|
private void ResetButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.IsRunning = false;
|
MainViewRunningState.IsRunning = false;
|
||||||
|
|
||||||
runningState.CurrentPeriod = Period.Work;
|
MainViewRunningState.CurrentPeriod = Period.Work;
|
||||||
runningState.MinutesLeft = WorkMinutes;
|
MainViewRunningState.MinutesLeft = WorkMinutes;
|
||||||
runningState.SecondsLeft = 0;
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
|
|
||||||
|
ClearScheduledNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Plus1Button_Click(object sender, RoutedEventArgs e)
|
private void Plus1Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.MinutesLeft += 1;
|
MainViewRunningState.MinutesLeft += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Plus5Button_Click(object sender, RoutedEventArgs e)
|
private void Plus5Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.MinutesLeft += 5;
|
MainViewRunningState.MinutesLeft += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Plus10Button_Click(object sender, RoutedEventArgs e)
|
private void Plus10Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AppBarButton b = sender as AppBarButton;
|
AppBarButton b = sender as AppBarButton;
|
||||||
runningState.MinutesLeft += 10;
|
MainViewRunningState.MinutesLeft += 10;
|
||||||
}
|
}
|
||||||
private void OnSuspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
|
private void OnSuspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -253,18 +280,46 @@ namespace PomoTime
|
|||||||
minutes["BreakMinutes"] = BreakMinutes;
|
minutes["BreakMinutes"] = BreakMinutes;
|
||||||
minutes["LongBreakMinutes"] = LongBreakMinutes;
|
minutes["LongBreakMinutes"] = LongBreakMinutes;
|
||||||
roamingSettings.Values["Minutes"] = minutes;
|
roamingSettings.Values["Minutes"] = minutes;
|
||||||
|
|
||||||
|
SuspendTime = DateTime.Now;
|
||||||
deferral.Complete();
|
deferral.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnResuming(object sender, Object e)
|
||||||
|
{
|
||||||
|
TimeSpan TimeFromSuspend = DateTime.Now - SuspendTime;
|
||||||
|
if(!MainViewRunningState.IsRunning)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(TimeFromSuspend.TotalSeconds >= MainViewRunningState.MinutesLeft * 60 + MainViewRunningState.SecondsLeft)
|
||||||
|
{
|
||||||
|
MainViewRunningState.IsRunning = false;
|
||||||
|
MainViewRunningState.MinutesLeft = 0;
|
||||||
|
MainViewRunningState.SecondsLeft = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(TimeFromSuspend.Seconds > MainViewRunningState.SecondsLeft)
|
||||||
|
{
|
||||||
|
MainViewRunningState.MinutesLeft -= TimeFromSuspend.Minutes + 1;
|
||||||
|
MainViewRunningState.SecondsLeft = MainViewRunningState.SecondsLeft + 60 - TimeFromSuspend.Seconds;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainViewRunningState.MinutesLeft -= TimeFromSuspend.Minutes;
|
||||||
|
MainViewRunningState.SecondsLeft -= TimeFromSuspend.Seconds;
|
||||||
|
}
|
||||||
|
|
||||||
private void MainPageLoaded(object sender, RoutedEventArgs e)
|
private void MainPageLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
ThreadPoolTimer timer = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
|
ThreadPoolTimer timer = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
|
||||||
{
|
{
|
||||||
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
await Dispatcher.RunAsync(CoreDispatcherPriority.High,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
timer_Tick();
|
timer_Tick();
|
||||||
});
|
});
|
||||||
}, TimeSpan.FromSeconds(1));
|
}, TimeSpan.FromSeconds(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="44844StepanUsatyuk.PomoTime"
|
Name="44844StepanUsatyuk.PomoTime"
|
||||||
Publisher="CN=D7EE55C2-4D4B-40F8-8EE5-CC4CEBCE2133"
|
Publisher="CN=D7EE55C2-4D4B-40F8-8EE5-CC4CEBCE2133"
|
||||||
Version="1.0.0.0" />
|
Version="1.0.1.0" />
|
||||||
|
|
||||||
<mp:PhoneIdentity PhoneProductId="4d8bddac-8ab7-4c19-b3c7-7b5a27b87594" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
<mp:PhoneIdentity PhoneProductId="4d8bddac-8ab7-4c19-b3c7-7b5a27b87594" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,13 @@
|
|||||||
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
|
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
|
||||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||||
<PackageCertificateThumbprint>037FCF0D18772F50AACCB9F3A4F9061066C3F0CB</PackageCertificateThumbprint>
|
<PackageCertificateThumbprint>037FCF0D18772F50AACCB9F3A4F9061066C3F0CB</PackageCertificateThumbprint>
|
||||||
|
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||||
|
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||||
|
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||||
|
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||||
|
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
|
||||||
|
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||||
|
<AppxBundle>Always</AppxBundle>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
|||||||
Reference in New Issue
Block a user