More index features.

This commit is contained in:
AnduinXue
2024-01-13 07:15:04 +00:00
parent ab21382973
commit 5a0c99a95b
9 changed files with 278 additions and 55 deletions
@@ -1,11 +1,59 @@
using Aiursoft.ChessServer.Data;
using Aiursoft.ChessServer.Models;
using Aiursoft.CSTools.Services;
using Microsoft.AspNetCore.Mvc;
namespace Aiursoft.ChessServer.Controllers;
public class HomeController : ControllerBase
public class HomeController : Controller
{
private readonly Counter _counter;
private readonly InMemoryDatabase _database;
public HomeController(
Counter counter,
InMemoryDatabase database)
{
_counter = counter;
_database = database;
}
public IActionResult Index()
{
return this.Ok("Welcome to chess server! Please go to '/games/12345.json' to view more.");
var model = new IndexViewModel(_database.Challenges);
return View(model);
}
}
public IActionResult Create(Guid playerId)
{
var iHaveAChallenge = _database.Challenges.FirstOrDefault(t => t.Value.Creator.Id == playerId);
if (iHaveAChallenge.Value != null)
{
return RedirectToAction(nameof(Room), new { id = iHaveAChallenge.Key });
}
var model = new CreateChallengeViewModel();
return View(model);
}
[HttpPost]
public IActionResult Create(CreateChallengeViewModel model)
{
var player = _database.GetOrAddPlayer(model.CreatorId);
var challenge = new Challenge(player)
{
RoleRule = model.RoleRule,
Message = model.Message,
Permission = model.Permission,
TimeLimit = model.TimeLimit,
};
var uniqueId = _counter.GetUniqueNo();
_database.Challenges.TryAdd(uniqueId, challenge);
return RedirectToAction(nameof(Room), new { id = uniqueId });
}
public IActionResult Room(int id)
{
// Not implemented.
return Ok();
}
}
@@ -9,6 +9,8 @@ public class InMemoryDatabase : ISingletonDependency
private ConcurrentDictionary<int, Game> Games { get; } = new();
private ConcurrentDictionary<Guid, Player> Players { get; } = new();
public ConcurrentDictionary<int, Challenge> Challenges { get; } = new();
public GameContext[] GetActiveGames()
{
+10 -2
View File
@@ -27,9 +27,17 @@ public enum ChallengePermission
public class Challenge
{
public Guid CreatorId { get; set; }
public Challenge(Player creator)
{
Creator = creator;
}
public Guid? AccepterId { get; set; } = null;
public Player Creator { get; set; }
public string Message { get; set; } = "A chess room.";
public Player? Accepter { get; set; } = null;
public Game? Game { get; set; } = null;
public RoleRule RoleRule { get; set; } = RoleRule.Random;
@@ -0,0 +1,14 @@
namespace Aiursoft.ChessServer.Models;
public class CreateChallengeViewModel
{
public Guid CreatorId { get; set; }
public string Message { get; set; } = "A chess room.";
public RoleRule RoleRule { get; set; } = RoleRule.Random;
public TimeSpan TimeLimit { get; set; } = TimeSpan.FromMinutes(10);
public ChallengePermission Permission { get; set; } = ChallengePermission.Public;
}
@@ -0,0 +1,13 @@
using System.Collections.Concurrent;
namespace Aiursoft.ChessServer.Models;
public class IndexViewModel
{
public ConcurrentDictionary<int, Challenge> Challenges { get; }
public IndexViewModel(ConcurrentDictionary<int, Challenge> challenges)
{
Challenges = challenges;
}
}
@@ -0,0 +1,81 @@
@model Aiursoft.ChessServer.Models.CreateChallengeViewModel
<div class="jumbotron">
<div class="container">
<h1 class="display-4">Create a new room</h1>
<p class="lead">Enter your room name and start a new game!</p>
<p>
<a class="btn btn-secondary btn-lg mt-4" asp-controller="Home" asp-action="Index">Back to list</a>
</p>
</div>
</div>
<div class="container mt-4" id="functions">
<div class="row no-gutters">
<div class="card mb-2 col-sm-12 px-1">
<div class="card-body">
<h5 class="card-title">Create a new room</h5>
<form asp-controller="Home" asp-action="Create" method="post">
<input type="hidden" asp-for="CreatorId"/>
<div class="form-group">
<label asp-for="Message"></label>
<input asp-for="Message" class="form-control"/>
<span asp-validation-for="Message" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="RoleRule"></label>
<select asp-for="RoleRule" class="form-control">
<option value="Random">Random</option>
<option value="CreatorWhite">Creator White</option>
<option value="AccepterWhite">Accepter White</option>
</select>
<span asp-validation-for="RoleRule" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TimeLimit"></label>
<select asp-for="TimeLimit" class="form-control">
<option value="00:01:00">1 minutes</option>
<option value="00:03:00">3 minutes</option>
<option value="00:05:00">5 minutes</option>
<option value="00:10:00">10 minutes</option>
<option value="00:15:00">15 minutes</option>
<option value="00:30:00">30 minutes</option>
<option value="01:00:00">1 hour</option>
<option value="02:00:00">2 hours</option>
</select>
<span asp-validation-for="TimeLimit" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Permission"></label>
<select asp-for="Permission" class="form-control">
<option value="Public">Public</option>
<option value="Unlisted">Unlisted</option>
</select>
<span asp-validation-for="Permission" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Create</button>
</div>
</form>
</div>
</div>
</div>
</div>
@section scripts
{
<script type="module">
import { getUserId } from "/scripts/player.js";
const playerId = getUserId();
const hiddenInput = document.querySelector("#CreatorId");
if (playerId) {
hiddenInput.value = playerId;
}
</script>
}
@@ -0,0 +1,57 @@
@model Aiursoft.ChessServer.Models.IndexViewModel
<div class="jumbotron">
<div class="container">
<h1 class="display-4">Welcome challenger!</h1>
<p class="lead">Join a room, or create a room!</p>
<p>
<button class="btn btn-success btn-lg mt-4" role="button">Auto join</button>
<a class="btn btn-secondary btn-lg mt-4" role="button" id="createButton" asp-controller="Home" asp-action="Create">Create a new room</a>
</p>
</div>
</div>
<div class="container mt-4">
<div class="row no-gutters">
<div class="col-sm-12 px-1">
<div class="card mb-2 tests-card">
<div class="card-body">
<h5 class="card-title">Public games</h5>
<div class="table-responsive">
<table class="table table-striped table-hover table-sm" id="logTable">
<tr>
<th>Room Name</th>
<th>Creator</th>
<th>Action</th>
</tr>
@foreach (var item in Model.Challenges)
{
<tr>
<td>@item.Value.Message</td>
<td>@item.Value.Creator.NickName</td>
<td>
<button class="btn btn-sm btn-primary" data-room-id="@item.Key">Join</button>
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@section scripts
{
<script type="module">
import { getUserId } from "/scripts/player.js";
const createButton = document.getElementById("createButton");
const playerId = getUserId();
// Append player id to create button.
if (playerId) {
createButton.href += `?playerId=${playerId}`;
}
</script>
}
@@ -2,69 +2,69 @@
<html lang="en" class="h-100">
<head>
<meta charset="utf-8" />
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" type="image/x-icon" href="~/favicon.ico" />
<link rel="icon" type="image/x-icon" href="~/favicon.ico"/>
<title>Game - Aiursoft Chess Server</title>
<link rel="stylesheet" href="~/node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/node_modules/@@aiursoft/autodark.js/dist/css/autodark.min.css" />
<link rel="stylesheet" href="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.css" />
<link rel="stylesheet" href="~/node_modules/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/node_modules/@@aiursoft/autodark.js/dist/css/autodark.min.css"/>
<link rel="stylesheet" href="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.css"/>
</head>
<body class="d-flex flex-column h-100 pt-5">
<header>
<nav class="navbar fixed-top navbar-expand-md mb-3">
<div class="container">
<a class="navbar-brand" href="https://www.aiursoft.cn">
Aiursoft
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
<header>
<nav class="navbar fixed-top navbar-expand-md mb-3">
<div class="container">
<a class="navbar-brand" href="https://www.aiursoft.cn">
Aiursoft
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" asp-controller="Home" asp-action="Index">Chess</a>
</li>
</ul>
<div class="form-inline">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" asp-controller="Home" asp-action="Index">Chess</a>
<li class="nav-item">
<a class="nav-link" title="Manage" id="player-nick-name" href="#">未登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
<i class="fab fa-gitlab"></i>
View on GitLab
</a>
</li>
</ul>
<div class="form-inline">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" title="Manage" id="player-nick-name" href="#">未登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
<i class="fab fa-gitlab"></i>
View on GitLab
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<div class="container mt-5">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="footer mt-auto py-3">
<div class="container">
&copy; @DateTime.UtcNow.Year - Aiursoft.ChessServer - <a
href="https://gitlab.aiursoft.cn/aiursoft/chessserver">GitLab</a>
</div>
</footer>
</nav>
</header>
<script type="module" src="~/node_modules/jquery/dist/jquery.min.js" defer></script>
<script type="module" src="~/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
<script type="module" src="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.js" defer></script>
<script type="module" src="~/scripts/layout.js" defer></script>
@(await RenderSectionAsync("scripts", false))
@RenderBody()
<footer class="footer mt-auto py-3">
<div class="container">
&copy; @DateTime.UtcNow.Year - Aiursoft.ChessServer -
<a
href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
GitLab
</a>
</div>
</footer>
<script type="module" src="~/node_modules/jquery/dist/jquery.min.js" defer></script>
<script type="module" src="~/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
<script type="module" src="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.js" defer></script>
<script type="module" src="~/scripts/layout.js" defer></script>
@(await RenderSectionAsync("scripts", false))
</body>
</html>
</html>
@@ -22,4 +22,4 @@ const changeName = async function (newName) {
await fetch(`/players/${getUserId()}/new-name/${newName}`, { method: 'PUT' });
}
export { getUserName, changeName };
export { getUserId, getUserName, changeName };