diff --git a/Hurl.sln b/Hurl.sln
index 7f08d63..6c07c9b 100644
--- a/Hurl.sln
+++ b/Hurl.sln
@@ -12,6 +12,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hurl.Library", "Source\Hurl
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hurl.Settings", "Source\Hurl.Settings\Hurl.Settings.csproj", "{C4DB15A3-1D60-437C-BD29-688E9E280E87}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hurl.Timely", "Source\Hurl.Timely\Hurl.Timely.csproj", "{F3A1BB02-F009-439B-A805-01A57B7F2009}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -72,6 +74,30 @@ Global
{C4DB15A3-1D60-437C-BD29-688E9E280E87}.Release|x64.Build.0 = Release|x64
{C4DB15A3-1D60-437C-BD29-688E9E280E87}.Release|x86.ActiveCfg = Release|x64
{C4DB15A3-1D60-437C-BD29-688E9E280E87}.Release|x86.Build.0 = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|Any CPU.Build.0 = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|Any CPU.Deploy.0 = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x64.ActiveCfg = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x64.Build.0 = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x64.Deploy.0 = Debug|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x86.ActiveCfg = Debug|x86
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x86.Build.0 = Debug|x86
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Debug|x86.Deploy.0 = Debug|x86
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|Any CPU.ActiveCfg = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|Any CPU.Build.0 = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|Any CPU.Deploy.0 = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|ARM64.Build.0 = Release|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|ARM64.Deploy.0 = Release|ARM64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x64.ActiveCfg = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x64.Build.0 = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x64.Deploy.0 = Release|x64
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x86.ActiveCfg = Release|x86
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x86.Build.0 = Release|x86
+ {F3A1BB02-F009-439B-A805-01A57B7F2009}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml b/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml
new file mode 100644
index 0000000..8ce0d2b
--- /dev/null
+++ b/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml.cs b/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml.cs
new file mode 100644
index 0000000..9d86d62
--- /dev/null
+++ b/Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml.cs
@@ -0,0 +1,60 @@
+using Hurl.Library.Models;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Hurl.BrowserSelector.Controls
+{
+ public partial class ToggleBrowserButton : UserControl
+ {
+ public ToggleBrowserButton()
+ {
+ InitializeComponent();
+ // Example: Browsers should be set externally, e.g. via binding or code
+ }
+
+ public static readonly DependencyProperty SelectedBrowserProperty =
+ DependencyProperty.Register(
+ nameof(SelectedBrowser),
+ typeof(Browser),
+ typeof(ToggleBrowserButton),
+ new PropertyMetadata(null));
+
+ public Browser SelectedBrowser
+ {
+ get => (Browser)GetValue(SelectedBrowserProperty);
+ set => SetValue(SelectedBrowserProperty, value);
+ }
+
+ public static readonly RoutedEvent BrowserToggledEvent =
+ EventManager.RegisterRoutedEvent(
+ nameof(BrowserToggled),
+ RoutingStrategy.Bubble,
+ typeof(RoutedEventHandler),
+ typeof(ToggleBrowserButton));
+
+ public event RoutedEventHandler BrowserToggled
+ {
+ add => AddHandler(BrowserToggledEvent, value);
+ remove => RemoveHandler(BrowserToggledEvent, value);
+ }
+
+ private void ToggleButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (Resources["BrowserMenu"] is ContextMenu menu)
+ {
+ menu.PlacementTarget = sender as Button;
+ menu.IsOpen = true;
+ }
+ }
+
+ private void BrowserMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ if (((MenuItem)sender).Tag is Browser browser)
+ {
+ SelectedBrowser = browser;
+ RaiseEvent(new RoutedEventArgs(BrowserToggledEvent));
+ }
+ }
+ }
+}
diff --git a/Source/Hurl.BrowserSelector/Services/TimelyService.cs b/Source/Hurl.BrowserSelector/Services/TimelyService.cs
new file mode 100644
index 0000000..2610123
--- /dev/null
+++ b/Source/Hurl.BrowserSelector/Services/TimelyService.cs
@@ -0,0 +1,69 @@
+using Hurl.Library;
+using Hurl.Library.Models;
+using System;
+using System.Diagnostics;
+using System.IO;
+
+namespace Hurl.BrowserSelector.Services;
+
+internal class TimelyService
+{
+ public static bool CheckAndLaunch(string url)
+ {
+ var Path_TempDef = Path.Combine(Constants.APP_SETTINGS_DIR, "TempDefault.json");
+ if (File.Exists(Path_TempDef))
+ {
+ var obj = JsonOperations.FromJsonToModel(Path_TempDef);
+ if (obj?.ValidTill >= DateTime.Now)
+ {
+ Process.Start(obj.TargetBrowser.ExePath, url);
+ Debug.WriteLine(obj.TargetBrowser.ExePath);
+ return true;
+ }
+ else
+ {
+ File.Delete(Path_TempDef);
+ }
+ }
+ return false;
+ }
+
+ public static void Create(int mins, Browser browser)
+ {
+ var dataObject = new TemporaryDefaultBrowser()
+ {
+ TargetBrowser = browser,
+ SelectedAt = DateTime.Now,
+ ValidTill = DateTime.Now.AddMinutes(mins)
+ };
+
+ JsonOperations.FromModelToJson(dataObject, Path.Combine(Constants.APP_SETTINGS_DIR, "TempDefault.json"));
+ }
+
+ public static TemporaryDefaultBrowser? Get()
+ {
+ var Path_TempDef = Path.Combine(Constants.APP_SETTINGS_DIR, "TempDefault.json");
+ if (File.Exists(Path_TempDef))
+ {
+ var obj = JsonOperations.FromJsonToModel(Path_TempDef);
+ if (obj?.ValidTill >= DateTime.Now)
+ {
+ return obj;
+ }
+ else
+ {
+ File.Delete(Path_TempDef);
+ }
+ }
+ return null;
+ }
+
+ internal static void DeleteCurrent()
+ {
+ var Path_TempDef = Path.Combine(Constants.APP_SETTINGS_DIR, "TempDefault.json");
+ if (File.Exists(Path_TempDef))
+ {
+ File.Delete(Path_TempDef);
+ }
+ }
+}
diff --git a/Source/Hurl.Timely/App.xaml b/Source/Hurl.Timely/App.xaml
new file mode 100644
index 0000000..2a91688
--- /dev/null
+++ b/Source/Hurl.Timely/App.xaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Hurl.Timely/App.xaml.cs b/Source/Hurl.Timely/App.xaml.cs
new file mode 100644
index 0000000..0040a1d
--- /dev/null
+++ b/Source/Hurl.Timely/App.xaml.cs
@@ -0,0 +1,50 @@
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Controls.Primitives;
+using Microsoft.UI.Xaml.Data;
+using Microsoft.UI.Xaml.Input;
+using Microsoft.UI.Xaml.Media;
+using Microsoft.UI.Xaml.Navigation;
+using Microsoft.UI.Xaml.Shapes;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace Hurl.Timely
+{
+ ///
+ /// Provides application-specific behavior to supplement the default Application class.
+ ///
+ public partial class App : Application
+ {
+ private Window? _window;
+
+ ///
+ /// Initializes the singleton application object. This is the first line of authored code
+ /// executed, and as such is the logical equivalent of main() or WinMain().
+ ///
+ public App()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Invoked when the application is launched.
+ ///
+ /// Details about the launch request and process.
+ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
+ {
+ _window = new MainWindow();
+ _window.Activate();
+ }
+ }
+}
diff --git a/Source/Hurl.Timely/Hurl.Timely.csproj b/Source/Hurl.Timely/Hurl.Timely.csproj
new file mode 100644
index 0000000..7545658
--- /dev/null
+++ b/Source/Hurl.Timely/Hurl.Timely.csproj
@@ -0,0 +1,69 @@
+
+
+ Hurl Timely
+ Hurl Timely
+ 0.10.0
+ 0.10.0.27
+ Copyright (c) 2025 Chanakya
+ Hurl
+ Chanakya
+ U-C-S
+ Hurl.Timely
+ WinExe
+ net9.0-windows10.0.26100.0
+ 10.0.17763.0
+ Hurl.Timely
+ app.manifest
+ x86;x64;ARM64
+ win-x86;win-x64;win-arm64
+ win-$(Platform).pubxml
+ true
+ enable
+ true
+ 10.0.26100.56
+ 10.0.19041.0
+ 10.0.19041.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+ DISABLE_XAML_GENERATED_MAIN
+
+
+
+
+ true
+
+
+
+
+ False
+ True
+ False
+ True
+
+
\ No newline at end of file
diff --git a/Source/Hurl.Timely/MainWindow.xaml b/Source/Hurl.Timely/MainWindow.xaml
new file mode 100644
index 0000000..e560d45
--- /dev/null
+++ b/Source/Hurl.Timely/MainWindow.xaml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ For a period of time
+ Till a specific time
+ Until I turn it off
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Choose the browser
+
+ For a period of time
+ Till a specific time
+ Until I turn it off
+
+
+
+
+
+
+ An existing timed default browser is already running
+
+
+
+
+
diff --git a/Source/Hurl.Timely/MainWindow.xaml.cs b/Source/Hurl.Timely/MainWindow.xaml.cs
new file mode 100644
index 0000000..b05fbf7
--- /dev/null
+++ b/Source/Hurl.Timely/MainWindow.xaml.cs
@@ -0,0 +1,24 @@
+using Microsoft.UI.Xaml;
+using System;
+
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace Hurl.Timely
+{
+ ///
+ /// An empty window that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ this.ExtendsContentIntoTitleBar = true;
+
+ //window.AppWindow.IsShownInSwitchers = false;
+ this.AppWindow.ResizeClient(new Windows.Graphics.SizeInt32(600, 320));
+
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/Source/Hurl.Timely/Program.cs b/Source/Hurl.Timely/Program.cs
new file mode 100644
index 0000000..f5fb7d2
--- /dev/null
+++ b/Source/Hurl.Timely/Program.cs
@@ -0,0 +1,60 @@
+using Microsoft.Windows.ApplicationModel.DynamicDependency;
+using System;
+
+namespace Hurl.Timely;
+
+public class Program
+{
+ [global::System.Runtime.InteropServices.DllImport("Microsoft.ui.xaml.dll")]
+ [global::System.Runtime.InteropServices.DefaultDllImportSearchPaths(global::System.Runtime.InteropServices.DllImportSearchPath.SafeDirectories)]
+ private static extern void XamlCheckProcessRequirements();
+
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.UI.Xaml.Markup.Compiler", " 3.0.0.2408")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.STAThreadAttribute]
+ static void Main(string[] args)
+ {
+ InitializeWASDK();
+ XamlCheckProcessRequirements();
+
+ global::WinRT.ComWrappersSupport.InitializeComWrappers();
+ global::Microsoft.UI.Xaml.Application.Start((p) =>
+ {
+ var context = new global::Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext(global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread());
+ global::System.Threading.SynchronizationContext.SetSynchronizationContext(context);
+ new App();
+ });
+ }
+
+ public static bool InitializeWASDK()
+ {
+ uint minSupportedMinorVersion = global::Microsoft.WindowsAppSDK.Release.MajorMinor; // 0x00010005
+ uint maxSupportedMinorVersion = 0x00010007;
+ for (uint version = minSupportedMinorVersion; version <= maxSupportedMinorVersion; version++)
+ {
+ if (global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.TryInitialize(version, out _))
+ return true;
+ }
+
+ // Failure in trying to initialize supported versions.
+ // Try one last time in the WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE way
+ // that None property does.
+ try
+ {
+ string versionTag = global::Microsoft.WindowsAppSDK.Release.VersionTag;
+ var minVersion = new PackageVersion(global::Microsoft.WindowsAppSDK.Runtime.Version.UInt64);
+ var options = global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnNoMatch_ShowUI;
+ int hr = 0;
+ if (!global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.TryInitialize(minSupportedMinorVersion, versionTag, minVersion, options, out hr))
+ {
+ Environment.Exit(hr);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Error in initializing the default version of Windows App Runtime", ex);
+ }
+
+ return false;
+ }
+}
diff --git a/Source/Hurl.Timely/Properties/launchSettings.json b/Source/Hurl.Timely/Properties/launchSettings.json
new file mode 100644
index 0000000..c22dce1
--- /dev/null
+++ b/Source/Hurl.Timely/Properties/launchSettings.json
@@ -0,0 +1,10 @@
+{
+ "profiles": {
+ "Hurl.Timely (Package)": {
+ "commandName": "MsixPackage"
+ },
+ "Hurl.Timely (Unpackaged)": {
+ "commandName": "Project"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Hurl.Timely/app.manifest b/Source/Hurl.Timely/app.manifest
new file mode 100644
index 0000000..0f101d5
--- /dev/null
+++ b/Source/Hurl.Timely/app.manifest
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PerMonitorV2
+
+
+
\ No newline at end of file