Skip to content

Commit 6509335

Browse files
maui client
1 parent fd2964d commit 6509335

47 files changed

Lines changed: 1442 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version = "1.0" encoding = "UTF-8" ?>
2+
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:local="clr-namespace:CodeBreaker.MAUI"
5+
x:Class="CodeBreaker.MAUI.App"
6+
UserAppTheme="Dark">
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
11+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
12+
<ResourceDictionary Source="Views/Templates/CodebreakerTemplates.xaml" />
13+
</ResourceDictionary.MergedDictionaries>
14+
</ResourceDictionary>
15+
</Application.Resources>
16+
</Application>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace CodeBreaker.MAUI;
2+
3+
public partial class App : Application
4+
{
5+
public App()
6+
{
7+
InitializeComponent();
8+
9+
MainPage = new AppShell();
10+
}
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Shell
3+
x:Class="CodeBreaker.MAUI.AppShell"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:CodeBreaker.MAUI"
7+
xmlns:pages="clr-namespace:CodeBreaker.MAUI.Views.Pages"
8+
Shell.FlyoutBehavior="Disabled">
9+
10+
<ShellContent
11+
Title="Home"
12+
ContentTemplate="{DataTemplate pages:GamePage}"
13+
Route="GamePage" />
14+
15+
</Shell>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace CodeBreaker.MAUI;
2+
3+
public partial class AppShell : Shell
4+
{
5+
public AppShell()
6+
{
7+
InitializeComponent();
8+
}
9+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net7.0-maccatalyst;net7.0-ios;net7.0-android</TargetFrameworks>
5+
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
6+
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
7+
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
8+
<OutputType>Exe</OutputType>
9+
<RootNamespace>CodeBreaker.MAUI</RootNamespace>
10+
<UseMaui>true</UseMaui>
11+
<SingleProject>true</SingleProject>
12+
<ImplicitUsings>enable</ImplicitUsings>
13+
<Nullable>enable</Nullable>
14+
15+
<!-- Display name -->
16+
<ApplicationTitle>Codebreaker</ApplicationTitle>
17+
18+
<!-- App Identifier -->
19+
<ApplicationId>com.cninnovation.codebreaker.maui</ApplicationId>
20+
<ApplicationIdGuid>1918619D-8FC1-4FA0-A55D-00EFA4FF5DB7</ApplicationIdGuid>
21+
22+
<!-- Versions -->
23+
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
24+
<ApplicationVersion>2</ApplicationVersion>
25+
26+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
27+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
28+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
29+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
30+
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
31+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
32+
</PropertyGroup>
33+
34+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-android|AnyCPU'">
35+
<AndroidKeyStore>False</AndroidKeyStore>
36+
</PropertyGroup>
37+
38+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-android|AnyCPU'">
39+
<AndroidKeyStore>True</AndroidKeyStore>
40+
<AndroidSigningKeyStore>codebreakerandroid.keystore</AndroidSigningKeyStore>
41+
<AndroidSigningKeyAlias>key</AndroidSigningKeyAlias>
42+
</PropertyGroup>
43+
44+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-ios|AnyCPU'">
45+
<AndroidKeyStore>False</AndroidKeyStore>
46+
</PropertyGroup>
47+
48+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'">
49+
<AndroidKeyStore>False</AndroidKeyStore>
50+
</PropertyGroup>
51+
52+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-maccatalyst|AnyCPU'">
53+
<AndroidKeyStore>False</AndroidKeyStore>
54+
</PropertyGroup>
55+
56+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-maccatalyst|AnyCPU'">
57+
<AndroidKeyStore>False</AndroidKeyStore>
58+
</PropertyGroup>
59+
60+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-windows10.0.19041.0|AnyCPU'">
61+
<AndroidKeyStore>False</AndroidKeyStore>
62+
</PropertyGroup>
63+
64+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-windows10.0.19041.0|AnyCPU'">
65+
<AndroidKeyStore>False</AndroidKeyStore>
66+
</PropertyGroup>
67+
68+
<ItemGroup>
69+
<!-- App Icon -->
70+
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
71+
72+
<!-- Splash Screen -->
73+
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
74+
75+
<!-- Images -->
76+
<MauiImage Include="Resources\Images\*" />
77+
<MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />
78+
79+
<!-- Custom Fonts -->
80+
<MauiFont Include="Resources\Fonts\*" />
81+
82+
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
83+
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
84+
</ItemGroup>
85+
86+
<ItemGroup>
87+
<PackageReference Include="BastaSpring2023.Codebreaker.ViewModels" Version="1.0.0-preview.1.3" />
88+
<PackageReference Include="CommunityToolkit.Maui" Version="4.0.0" />
89+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
90+
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
91+
</ItemGroup>
92+
93+
<ItemGroup>
94+
<MauiXaml Update="Views\Templates\CodebreakerTemplates.xaml">
95+
<Generator>MSBuild:Compile</Generator>
96+
</MauiXaml>
97+
<MauiXaml Update="Views\Components\PegSelectionView.xaml">
98+
<Generator>MSBuild:Compile</Generator>
99+
</MauiXaml>
100+
</ItemGroup>
101+
102+
<ItemGroup>
103+
<EditorConfigFiles Remove="C:\githublearn\codebreaker\src\xaml\CodeBreaker.MAUI\.editorconfig" />
104+
</ItemGroup>
105+
106+
<ItemGroup>
107+
<None Remove="appsettings.json" />
108+
<None Remove="appsettings.Development.json" />
109+
<None Remove="appsettings.Production.json" />
110+
</ItemGroup>
111+
112+
<ItemGroup>
113+
<MauiAsset Include="appsettings.json">
114+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
115+
</MauiAsset>
116+
<MauiAsset Include="appsettings.Development.json">
117+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
118+
</MauiAsset>
119+
<MauiAsset Include="appsettings.Production.json">
120+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
121+
</MauiAsset>
122+
</ItemGroup>
123+
124+
</Project>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Globalization;
2+
using static CodeBreaker.Shared.Colors;
3+
4+
namespace CodeBreaker.MAUI.Converters;
5+
6+
public class ColornameToBrushConverter : IValueConverter
7+
{
8+
private readonly static Brush s_blackBrush = new SolidColorBrush(Colors.Black);
9+
private readonly static Brush s_whiteBrush = new SolidColorBrush(Colors.White);
10+
private readonly static Brush s_redBrush = new SolidColorBrush(Color.FromArgb("#d13438"));
11+
private readonly static Brush s_greenBrush = new SolidColorBrush(Color.FromArgb("#00ad56"));
12+
private readonly static Brush s_blueBrush = new SolidColorBrush(Color.FromArgb("#4f6bed"));
13+
private readonly static Brush s_yellowBrush = new SolidColorBrush(Color.FromArgb("#fce100"));
14+
private readonly static Brush s_emptyBrush = new SolidColorBrush(Color.FromArgb("#a0aeb2"));
15+
16+
public Brush BlackBrush { get; set; } = s_blackBrush;
17+
public Brush WhiteBrush { get; set; } = s_whiteBrush;
18+
public Brush RedBrush { get; set; } = s_redBrush;
19+
public Brush GreenBrush { get; set; } = s_greenBrush;
20+
public Brush BlueBrush { get; set; } = s_blueBrush;
21+
public Brush YellowBrush { get; set; } = s_yellowBrush;
22+
private Brush EmptyBrush { get; set; } = s_emptyBrush;
23+
24+
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
25+
{
26+
// with .NET MAUI (contrary to other XAML technologies,
27+
// the converter is invoked many times,
28+
// often with null values, but also with the MainPage passed as value
29+
if (value is null)
30+
return null;
31+
32+
if (value is not string guessPeg)
33+
return null;
34+
35+
return guessPeg switch
36+
{
37+
Black => BlackBrush,
38+
White => WhiteBrush,
39+
Red => RedBrush,
40+
Green => GreenBrush,
41+
Blue => BlueBrush,
42+
Yellow => YellowBrush,
43+
_ => EmptyBrush
44+
};
45+
}
46+
47+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
48+
throw new NotImplementedException();
49+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using CodeBreaker.ViewModels;
2+
3+
using System.Globalization;
4+
5+
namespace CodeBreaker.MAUI.Converters;
6+
7+
public class GameStatusToIsVisibleConverter : IValueConverter
8+
{
9+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
10+
{
11+
static bool GetStartVisibility(GameMode gameMode) =>
12+
gameMode is not (GameMode.Started or GameMode.MoveSet);
13+
14+
static bool GetRunningVisibility(GameMode gameMode) =>
15+
!(gameMode == GameMode.NotRunning);
16+
17+
static bool GetCancelVisibility(GameMode gameMode) =>
18+
(gameMode is GameMode.Started or GameMode.MoveSet);
19+
20+
string uiCategory = parameter?.ToString() ?? throw new InvalidOperationException("Pass a parameter to this converter");
21+
22+
23+
if (value is GameMode gameMode)
24+
{
25+
return uiCategory switch
26+
{
27+
"Start" => GetStartVisibility(gameMode),
28+
"Running" => GetRunningVisibility(gameMode),
29+
"Cancelable" => GetCancelVisibility(gameMode),
30+
_ => throw new InvalidOperationException("Invalid parameter value")
31+
};
32+
}
33+
else
34+
{
35+
throw new InvalidOperationException("GameStatusToVisibilityConverter received an incorrect value type");
36+
}
37+
}
38+
39+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
40+
throw new NotImplementedException();
41+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Globalization;
2+
3+
namespace CodeBreaker.MAUI.Converters;
4+
5+
internal class IntToEnumerableConverter : IValueConverter
6+
{
7+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
8+
{
9+
if (value is not int count)
10+
throw new ArgumentException("The value needs to be an integer");
11+
12+
return Enumerable.Range(0, count);
13+
}
14+
15+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
16+
throw new NotImplementedException();
17+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using CodeBreaker.ViewModels;
2+
3+
using System.Globalization;
4+
5+
namespace CodeBreaker.MAUI.Converters;
6+
7+
internal class SelectionAndKeyPegToKeyVisibleConverter : IValueConverter
8+
{
9+
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
10+
{
11+
if (value is null) return null;
12+
ArgumentNullException.ThrowIfNull(parameter);
13+
14+
if (value is SelectionAndKeyPegs selection && int.TryParse(parameter.ToString(), out int ix ))
15+
return ix < selection.KeyPegs.White + selection.KeyPegs.Black;
16+
17+
return false;
18+
}
19+
20+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
21+
throw new NotImplementedException();
22+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using CommunityToolkit.Maui;
2+
using CodeBreaker.ViewModels;
3+
using CodeBreaker.ViewModels.Services;
4+
using CodeBreaker.MAUI.Services;
5+
using CodeBreaker.Services;
6+
using Microsoft.Extensions.Configuration;
7+
using CodeBreaker.MAUI.Views.Pages;
8+
using CodeBreaker.Shared.Extensions;
9+
10+
namespace CodeBreaker.MAUI;
11+
12+
public static class MauiProgram
13+
{
14+
public static MauiApp CreateMauiApp()
15+
{
16+
#if DEBUG
17+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Development");
18+
#else
19+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Production");
20+
#endif
21+
22+
var builder = MauiApp.CreateBuilder();
23+
builder
24+
.UseMauiApp<App>()
25+
.UseMauiCommunityToolkit()
26+
.ConfigureFonts(fonts =>
27+
{
28+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
29+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
30+
});
31+
32+
builder.Configuration.AddJsonStream(FileSystem.OpenAppPackageFileAsync("appsettings.json").Result);
33+
builder.Configuration.AddJsonStream(FileSystem.OpenAppPackageFileAsync($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json").Result);
34+
builder.Services.Configure<GamePageViewModelOptions>(options => options.EnableDialogs = true);
35+
builder.Services.AddScoped<IDialogService, MauiDialogService>();
36+
builder.Services.AddScoped<GamePageViewModel>();
37+
builder.Services.AddHttpClient<IGameClient, GameClient>(client =>
38+
{
39+
client.BaseAddress = new(builder.Configuration.GetRequired("ApiBase"));
40+
});
41+
builder.Services.AddTransient<GamePage>();
42+
return builder.Build();
43+
}
44+
}

0 commit comments

Comments
 (0)