Skip to content

Commit

Permalink
完成 Dev Page
Browse files Browse the repository at this point in the history
之後應該會對頁面的url規劃過一遍,還要想辦法把Dev Page藏起來
  • Loading branch information
aa89227 committed Aug 13, 2023
1 parent 69c6123 commit 8da3fb4
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 119 deletions.
4 changes: 4 additions & 0 deletions Client/Options/BackendApiOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
public class BackendApiOptions
{
public string BaseUrl { get; set; } = default!;
public BackendApiOptions()
{

}
}
5 changes: 3 additions & 2 deletions Client/Pages/Game.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public partial class Game

[Inject] private ISnackbar Snackbar { get; set; } = default!;
[Inject] private IOptions<BackendApiOptions> BackendApiOptions { get; set; } = default!;
private Uri BackendApiBaseUri => new(BackendApiOptions.Value.BaseUrl);

private HubConnection hubConnection = default!;
private readonly List<string> messages = new();
Expand All @@ -26,7 +27,7 @@ public partial class Game

protected override async Task OnInitializedAsync()
{
var url = new Uri(new Uri(BackendApiOptions.Value.BaseUrl), $"/monopoly?gameid={Id}");
var url = new Uri(BackendApiBaseUri, $"/monopoly?gameid={Id}");
hubConnection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
Expand All @@ -48,7 +49,7 @@ protected override async Task OnInitializedAsync()

private async Task GetMapFromApiAsync(string id)
{
var url = new Uri(new Uri(BackendApiOptions.Value.BaseUrl), $"/map?mapid={id}");
var url = new Uri(BackendApiBaseUri, $"/map?mapid={id}");
// map 從 Server 取得
var response = await new HttpClient().GetAsync(url);
if (!response.IsSuccessStatusCode)
Expand Down
109 changes: 1 addition & 108 deletions Client/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
@page "/"
@using Client.Options;
@using Microsoft.AspNetCore.SignalR.Client;
@using System.Security.Claims;
@using System.Net.Http.Headers;
@using Microsoft.Extensions.Options;
<MudStack>
@foreach (var item in Users)
{
<MudPaper Class="pa-3" Outlined Elevation="5">@item.Id</MudPaper>
}
</MudStack>
<MudTextField @bind-Value="Token" Label="Jwt Token" Variant="Variant.Outlined"
Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Add"
AdornmentColor="Color.Info"
OnAdornmentClick="AddUser" />
<MudButton OnClick="CreateGame" Variant="Variant.Filled" Color="Color.Primary">Create Game</MudButton>
<MudTextField @bind-Value="GameId" Label="Game Id" Variant="Variant.Outlined"
Adornment="Adornment.End"
Expand All @@ -25,101 +15,4 @@
{
<iframe src="/@[email protected]"></iframe>
}
</MudStack>

@code {
private string Token { get; set; } = "";
private List<string> Messages { get; set; } = new();
private List<User> Users { get; set; } = new();
private string UserId { get; set; } = string.Empty;
private string GameId { get; set; } = string.Empty;
private List<GameData> games = new();
[Inject] private ISnackbar Snackbar { get; set; } = default!;
[Inject] private IOptions<BackendApiOptions> BackendApiOptions { get; set; } = default!;

private async void CreateGame()
{
CreateGameBodyPayload bodyPayload = new(Users.Select(user => new Player(user.Id)).ToArray());
var url = new Uri(new Uri(BackendApiOptions.Value.BaseUrl), "/create-game");
var httpClient = new HttpClient();
var host = Users.FirstOrDefault();
if (host is null)
{
Snackbar.Add("請先加入使用者", Severity.Error);
return;
}
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", host.Token);
var response = await httpClient.PostAsJsonAsync(url, bodyPayload);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Snackbar.Add($"遊戲建立成功! Url: {content}", Severity.Success);
}
else
{
Snackbar.Add($"遊戲建立失敗! {response.StatusCode}", Severity.Error);
}
}

private async void AddUser()
{
var url = new Uri(new Uri(BackendApiOptions.Value.BaseUrl), "/whoami");
HubConnection hubConnection = new HubConnectionBuilder()
.WithAutomaticReconnect()
.WithUrl(url, opt =>
{
opt.AccessTokenProvider = () => Task.FromResult<string?>(Token);
})
.Build();
hubConnection.Closed += async (exception) =>
{
if (exception == null)
{
Snackbar.Add("中斷連線", Severity.Error);
}
else
{
Snackbar.Add($"中斷連線: {exception.Message}", Severity.Error);
}
await Task.CompletedTask;
};
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
hubConnection.On<List<string>>("WhoAmI", data =>
{
var userId = data.Single(d => d.StartsWith(ClaimTypes.Sid)).Substring(ClaimTypes.Sid.Length + 1);
tcs.SetResult(userId);
});

try
{
await hubConnection.StartAsync();
Snackbar.Add("連線成功!", Severity.Success);
await hubConnection.SendAsync("WhoAmI");
var tcst = await tcs.Task;
Users.Add(new(tcst, Token));
await hubConnection.StopAsync();
Token = string.Empty;
StateHasChanged();
}
catch (Exception ex)
{
Snackbar.Add(ex.Message, Severity.Error);
}
}

private void JoinGame()
{
games.Clear();
Users.ForEach(user =>
{
games.Add(new(GameId, user.Token));
});
StateHasChanged();
}

private record CreateGameBodyPayload(Player[] Players);
private record Player(string Id);

record GameData(string Id, string Token);
record User(string Id, string Token);
}
</MudStack>
121 changes: 121 additions & 0 deletions Client/Pages/Index.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using Client.Options;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Options;
using MudBlazor;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Security.Claims;

namespace Client.Pages;

public partial class Index
{
private List<User> Users { get; set; } = new();
private string GameId { get; set; } = string.Empty;
private readonly List<GameData> games = new();
[Inject] private ISnackbar Snackbar { get; set; } = default!;
[Inject] private IOptions<BackendApiOptions> BackendApiOptions { get; set; } = default!;
private Uri BackendApiBaseUri => new(BackendApiOptions.Value.BaseUrl);

protected override async Task OnInitializedAsync()
{
var tokens = await new HttpClient().GetFromJsonAsync<string[]>(new Uri(BackendApiBaseUri, "/tokens"));
if (tokens is null)
{
Snackbar.Add("取得 Token 失敗", Severity.Error);
return;
}

foreach(var token in tokens)
{
AddUser(token);
}
await base.OnInitializedAsync();
}

private async void CreateGame()
{
CreateGameBodyPayload bodyPayload = new(Users.Select(user => new Player(user.Id)).ToArray());
var url = new Uri(BackendApiBaseUri, "/create-game");
var httpClient = new HttpClient();
var host = Users.FirstOrDefault();
if (host is null)
{
Snackbar.Add("請先加入使用者", Severity.Error);
return;
}
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", host.Token);
var response = await httpClient.PostAsJsonAsync(url, bodyPayload);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Snackbar.Add($"遊戲建立成功! Url: {content}", Severity.Success);
}
else
{
Snackbar.Add($"遊戲建立失敗! {response.StatusCode}", Severity.Error);
}
}

private async void AddUser(string token)
{
var url = new Uri(BackendApiBaseUri, "/whoami");
HubConnection hubConnection = new HubConnectionBuilder()
.WithAutomaticReconnect()
.WithUrl(url, opt =>
{
opt.AccessTokenProvider = () => Task.FromResult<string?>(token);
})
.Build();
hubConnection.Closed += async (exception) =>
{
if (exception == null)
{
Snackbar.Add("中斷連線", Severity.Error);
}
else
{
Snackbar.Add($"中斷連線: {exception.Message}", Severity.Error);
}
await Task.CompletedTask;
};
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
hubConnection.On<List<string>>("WhoAmI", data =>
{
var userId = data.Single(d => d.StartsWith(ClaimTypes.Sid))[(ClaimTypes.Sid.Length + 1)..];
tcs.SetResult(userId);
});

try
{
await hubConnection.StartAsync();
Snackbar.Add("連線成功!", Severity.Success);
await hubConnection.SendAsync("WhoAmI");
var tcst = await tcs.Task;
Users.Add(new(tcst, token));
await hubConnection.StopAsync();
StateHasChanged();
}
catch (Exception ex)
{
Snackbar.Add(ex.Message, Severity.Error);
}
}

private void JoinGame()
{
games.Clear();
Users.ForEach(user =>
{
games.Add(new(GameId, user.Token));
});
StateHasChanged();
}

private record CreateGameBodyPayload(Player[] Players);
private record Player(string Id);

record GameData(string Id, string Token);
record User(string Id, string Token);
}
9 changes: 5 additions & 4 deletions Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.Configure<BackendApiOptions>(options =>
{
builder.Configuration.Bind(nameof(BackendApiOptions), options);
});
builder.Services.AddOptions<BackendApiOptions>()
.Configure(options =>
{
builder.Configuration.GetSection(nameof(BackendApiOptions)).Bind(options);
});
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddMudServices();

Expand Down
File renamed without changes.
File renamed without changes.
22 changes: 18 additions & 4 deletions Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
using Application.Usecases;
using Domain.Common;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.HttpResults;
using Server;
using Server.DataModels;
using Server.Hubs;
using Server.Repositories;
using Server.Services;
using SharedLibrary;
using System.Security.Claims;
using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -33,8 +31,16 @@
}));

// 如果 Bind Options 時需要依賴注入
builder.Services.AddScoped<IPlatformService, PlatformService>()
.AddSingleton<PlatformJwtEvents>();
// 如果是develop
if (builder.Environment.IsDevelopment())
{
builder.Services.AddScoped<IPlatformService, DevelopmentPlatformService>();
}
else
{
builder.Services.AddScoped<IPlatformService, PlatformService>();
}
builder.Services.AddSingleton<PlatformJwtEvents>();
builder.Services
.AddOptions<JwtBearerOptions>("Bearer")
.Configure<PlatformJwtEvents>((opt, jwtEvents) =>
Expand Down Expand Up @@ -91,4 +97,12 @@
}
});

#if DEBUG
app.MapGet("/tokens", () =>
{
DevelopmentPlatformService platformService = (DevelopmentPlatformService)app.Services.CreateScope().ServiceProvider.GetRequiredService<IPlatformService>();
return Results.Json(platformService.GetTokens());
});
#endif

app.Run();
3 changes: 2 additions & 1 deletion Server/Server.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>17212ac2-4825-4499-86b4-e5d490aaa1f8</UserSecretsId>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 8da3fb4

Please sign in to comment.