-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from Khiro95/dev
- Add Awqat Salaat WinUI app to support Windows 11. - Fix a critical error in date serialization on systems that use different calendars other than Gregorian. - Fix settings loss after the installation of Windows Updates (such as cumulative updates). - Show Hijri date in English when Display language is not set to Arabic.
- Loading branch information
Showing
112 changed files
with
2,824 additions
and
265 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<RootNamespace>AwqatSalaat</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" /> | ||
<PackageReference Include="TimeZoneConverter" Version="6.1.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Update="Properties\Resources.Designer.cs"> | ||
<DesignTime>True</DesignTime> | ||
<AutoGen>True</AutoGen> | ||
<DependentUpon>Resources.resx</DependentUpon> | ||
</Compile> | ||
<Compile Update="Properties\Settings.Designer.cs"> | ||
<DesignTimeSharedInput>True</DesignTimeSharedInput> | ||
<AutoGen>True</AutoGen> | ||
<DependentUpon>Settings.settings</DependentUpon> | ||
</Compile> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<EmbeddedResource Update="Properties\Resources.resx"> | ||
<Generator>PublicResXFileCodeGenerator</Generator> | ||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | ||
</EmbeddedResource> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="Properties\Settings.settings"> | ||
<Generator>PublicSettingsSingleFileGenerator</Generator> | ||
<LastGenOutput>Settings.Designer.cs</LastGenOutput> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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,70 @@ | ||
using System; | ||
using System.Globalization; | ||
|
||
namespace AwqatSalaat.Helpers | ||
{ | ||
public static class HijriDateHelper | ||
{ | ||
private static readonly DateTimeFormatInfo FallbackHijriDateTimeFormatInfo; | ||
|
||
static HijriDateHelper() | ||
{ | ||
// Start with the Arabic culture info since it provide all features | ||
var dateTimeFormat = new CultureInfo("ar-SA").DateTimeFormat; | ||
// Use English names as a fallback | ||
dateTimeFormat.MonthNames = new string[] | ||
{ | ||
"Muharram", | ||
"Safar", | ||
"Rabiʻ I", | ||
"Rabiʻ II", | ||
"Jumada I", | ||
"Jumada II", | ||
"Rajab", | ||
"Shaʻban", | ||
"Ramadan", | ||
"Shawwal", | ||
"Dhuʻl-Qiʻdah", | ||
"Dhuʻl-Hijjah", | ||
"" | ||
}; | ||
// MonthGenitiveNames is what provide values for formatter | ||
dateTimeFormat.MonthGenitiveNames = dateTimeFormat.MonthNames; | ||
|
||
FallbackHijriDateTimeFormatInfo = dateTimeFormat; | ||
} | ||
|
||
public static string Format(DateTime dateTime, string format, string language) | ||
{ | ||
if (string.IsNullOrEmpty(language)) | ||
{ | ||
language = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; | ||
} | ||
|
||
if (language.Length > 2) | ||
{ | ||
language = language.Substring(0, 2); | ||
} | ||
|
||
language += "-SA"; | ||
|
||
CultureInfo culture = CultureInfo.GetCultureInfo(language); | ||
|
||
DateTimeFormatInfo dateTimeFormat = culture.DateTimeFormat; | ||
|
||
if (dateTimeFormat.Calendar.GetType() != typeof(UmAlQuraCalendar)) | ||
{ | ||
if (culture.TextInfo.IsRightToLeft) | ||
{ | ||
dateTimeFormat = CultureInfo.GetCultureInfo("ar-SA").DateTimeFormat; | ||
} | ||
else | ||
{ | ||
dateTimeFormat = FallbackHijriDateTimeFormatInfo; | ||
} | ||
} | ||
|
||
return dateTime.ToString(format, dateTimeFormat); | ||
} | ||
} | ||
} |
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,74 @@ | ||
using System.ComponentModel; | ||
using System.Runtime.CompilerServices; | ||
using System.Threading; | ||
|
||
namespace AwqatSalaat.Helpers | ||
{ | ||
// using SynchronizationContext is necessary here when this class is used with Windows App SDK | ||
// because WinUI 3 still doesn't support dispatching PropertyChanged event to UI thread | ||
public class ObservableObject : INotifyPropertyChanged | ||
{ | ||
private class PropertyChangedEventState | ||
{ | ||
public readonly ObservableObject Sender; | ||
public readonly PropertyChangedEventArgs Args; | ||
|
||
public PropertyChangedEventState(ObservableObject sender, PropertyChangedEventArgs args) | ||
{ | ||
Sender = sender; | ||
Args = args; | ||
} | ||
} | ||
|
||
private event PropertyChangedEventHandler propertyChanged; | ||
private SynchronizationContext synchronizationContext; | ||
|
||
public event PropertyChangedEventHandler PropertyChanged | ||
{ | ||
add | ||
{ | ||
propertyChanged += value; | ||
|
||
if (synchronizationContext is null && !(SynchronizationContext.Current is null)) | ||
{ | ||
if (SynchronizationContext.Current.GetType().FullName.StartsWith("Microsoft.UI")) | ||
{ | ||
synchronizationContext = synchronizationContext ?? SynchronizationContext.Current; | ||
} | ||
} | ||
} | ||
remove | ||
{ | ||
propertyChanged -= value; | ||
} | ||
} | ||
|
||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) | ||
{ | ||
var args = new PropertyChangedEventArgs(propertyName); | ||
|
||
if (synchronizationContext is null) | ||
{ | ||
propertyChanged?.Invoke(this, args); | ||
} | ||
else | ||
{ | ||
synchronizationContext.Post((state) => | ||
{ | ||
PropertyChangedEventState eventState = (PropertyChangedEventState)state; | ||
eventState.Sender.propertyChanged?.Invoke(eventState.Sender, eventState.Args); | ||
}, | ||
new PropertyChangedEventState(this, args)); | ||
} | ||
} | ||
|
||
protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null) | ||
{ | ||
if (!Equals(field, value)) | ||
{ | ||
field = value; | ||
OnPropertyChanged(propertyName); | ||
} | ||
} | ||
} | ||
} |
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,72 @@ | ||
using System; | ||
using System.Windows.Input; | ||
|
||
namespace AwqatSalaat.Helpers | ||
{ | ||
/// <summary> | ||
/// A command whose sole purpose is to relay its functionality | ||
/// to other objects by invoking delegates. | ||
/// The default return value for the CanExecute method is 'true'. | ||
/// RaiseCanExecuteChanged needs to be called whenever | ||
/// CanExecute is expected to return a different value. | ||
/// </summary> | ||
public class RelayCommand : ICommand | ||
{ | ||
private readonly Action<object> _execute; | ||
private readonly Predicate<object> _canExecute; | ||
/// <summary> | ||
/// Raised when RaiseCanExecuteChanged is called. | ||
/// </summary> | ||
public event EventHandler CanExecuteChanged; | ||
/// <summary> | ||
/// Creates a new command that can always execute. | ||
/// </summary> | ||
/// <param name="execute">The execution logic.</param> | ||
public RelayCommand(Action<object> execute) | ||
: this(execute, null) | ||
{ | ||
} | ||
/// <summary> | ||
/// Creates a new command. | ||
/// </summary> | ||
/// <param name="execute">The execution logic.</param> | ||
/// <param name="canExecute">The execution status logic.</param> | ||
public RelayCommand(Action<object> execute, Predicate<object> canExecute) | ||
{ | ||
_execute = execute ?? throw new ArgumentNullException("execute"); | ||
_canExecute = canExecute; | ||
} | ||
/// <summary> | ||
/// Determines whether this RelayCommand can execute in its current state. | ||
/// </summary> | ||
/// <param name="parameter"> | ||
/// Data used by the command. If the command does not require data to be passed, | ||
/// this object can be set to null. | ||
/// </param> | ||
/// <returns>true if this command can be executed; otherwise, false.</returns> | ||
public bool CanExecute(object parameter) | ||
{ | ||
return _canExecute == null || _canExecute(parameter); | ||
} | ||
/// <summary> | ||
/// Executes the RelayCommand on the current command target. | ||
/// </summary> | ||
/// <param name="parameter"> | ||
/// Data used by the command. If the command does not require data to be passed, | ||
/// this object can be set to null. | ||
/// </param> | ||
public void Execute(object parameter) | ||
{ | ||
_execute(parameter); | ||
} | ||
/// <summary> | ||
/// Method used to raise the CanExecuteChanged event | ||
/// to indicate that the return value of the CanExecute | ||
/// method has changed. | ||
/// </summary> | ||
public void RaiseCanExecuteChanged() | ||
{ | ||
CanExecuteChanged?.Invoke(this, EventArgs.Empty); | ||
} | ||
} | ||
} |
Oops, something went wrong.