Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Hurl.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
42 changes: 42 additions & 0 deletions Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<UserControl
x:Class="Hurl.BrowserSelector.Controls.ToggleBrowserButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:Hurl.Library.Models;assembly=Hurl.Library"
xmlns:wpfui="http://schemas.lepo.co/wpfui/2022/xaml"
x:Name="Root">
<UserControl.Resources>
<ContextMenu x:Key="BrowserMenu" x:Name="BrowserMenu"
ItemsSource="{Binding Browsers, RelativeSource={RelativeSource AncestorType=UserControl}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}" />
<Setter Property="Tag" Value="{Binding}" />
<EventSetter Event="Click" Handler="BrowserMenuItem_Click" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</UserControl.Resources>
<Grid>
<wpfui:Button
Width="128"
Height="128"
Margin="4"
Padding="5,10,5,10"
Appearance="Transparent"
BorderBrush="Transparent"
Cursor="Hand"
ToolTip="{Binding SelectedBrowser.Name, ElementName=Root}"
Click="ToggleButton_Click">
<StackPanel>
<Image Source="{Binding SelectedBrowser.Icon, ElementName=Root}" Height="72" />
<wpfui:TextBlock
Margin="0,8,0,0"
FontTypography="Caption"
Text="{Binding SelectedBrowser.Name, ElementName=Root}"
TextAlignment="Center"
TextWrapping="NoWrap" />
</StackPanel>
</wpfui:Button>
</Grid>
</UserControl>
60 changes: 60 additions & 0 deletions Source/Hurl.BrowserSelector/Controls/ToggleBrowserButton.xaml.cs
Original file line number Diff line number Diff line change
@@ -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));
}
}
}
}
69 changes: 69 additions & 0 deletions Source/Hurl.BrowserSelector/Services/TimelyService.cs
Original file line number Diff line number Diff line change
@@ -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<TemporaryDefaultBrowser>(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<TemporaryDefaultBrowser>(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);
}
}
}
16 changes: 16 additions & 0 deletions Source/Hurl.Timely/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<Application
x:Class="Hurl.Timely.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Hurl.Timely">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>
50 changes: 50 additions & 0 deletions Source/Hurl.Timely/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private Window? _window;

/// <summary>
/// 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().
/// </summary>
public App()
{
InitializeComponent();
}

/// <summary>
/// Invoked when the application is launched.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
_window = new MainWindow();
_window.Activate();
}
}
}
69 changes: 69 additions & 0 deletions Source/Hurl.Timely/Hurl.Timely.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Title>Hurl Timely</Title>
<AssemblyName>Hurl Timely</AssemblyName>
<Version>0.10.0</Version>
<FileVersion>0.10.0.27</FileVersion>
<Copyright>Copyright (c) 2025 Chanakya</Copyright>
<Product>Hurl</Product>
<Company>Chanakya</Company>
<Authors>U-C-S</Authors>
<PackageId>Hurl.Timely</PackageId>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Hurl.Timely</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<UseWinUI>true</UseWinUI>
<Nullable>enable</Nullable>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsSdkPackageVersion>10.0.26100.56</WindowsSdkPackageVersion>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
</PropertyGroup>

<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(PkgMicrosoft_WindowsAppSDK)\include\WindowsAppSDK-VersionInfo.cs" />
<ProjectReference Include="..\Hurl.Library\Hurl.Library.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4948" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<PropertyGroup Label="Globals">
<WebView2EnableCsWinRTProjection>False</WebView2EnableCsWinRTProjection>
</PropertyGroup>

<PropertyGroup>
<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>
</PropertyGroup>

<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>

<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>
Loading