Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25c22b2ff5 |
@@ -6,7 +6,7 @@ on:
|
|||||||
- main
|
- main
|
||||||
|
|
||||||
env:
|
env:
|
||||||
VERSION: 1.9.4
|
VERSION: 1.9.5
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами)
|
# ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.9.4</Version>
|
<Version>1.9.5</Version>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Проект разработан с упором на производительность, архитектуру Vertical Slice, Native AOT (для бота) и удобство развертывания с использованием .NET Aspire.
|
Проект разработан с упором на производительность, архитектуру Vertical Slice, Native AOT (для бота) и удобство развертывания с использованием .NET Aspire.
|
||||||
|
|
||||||
**Текущая версия:** `v1.9.4`.
|
**Текущая версия:** `v1.9.5`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
image: git.codeanddice.ru/toutsu/gmrelay-bot:1.9.4
|
image: git.codeanddice.ru/toutsu/gmrelay-bot:1.9.5
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
@@ -30,7 +30,7 @@ services:
|
|||||||
- gmrelay
|
- gmrelay
|
||||||
|
|
||||||
web:
|
web:
|
||||||
image: git.codeanddice.ru/toutsu/gmrelay-web:1.9.4
|
image: git.codeanddice.ru/toutsu/gmrelay-web:1.9.5
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="nav-version">v1.9.4</div>
|
<div class="nav-version">v1.9.5</div>
|
||||||
</div>
|
</div>
|
||||||
</Authorized>
|
</Authorized>
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
|
|||||||
@@ -214,7 +214,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Desktop table *@
|
@* Desktop table *@
|
||||||
<div class="glass-card session-table-desktop animate-slide-up" style="padding: 0; overflow: hidden;">
|
<div class="glass-card session-table-desktop session-table-desktop-card animate-slide-up">
|
||||||
<table class="gm-table">
|
<table class="gm-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -237,19 +237,18 @@
|
|||||||
<span class="status-badge @GetStatusClass(session.Status)">@TranslateStatus(session.Status)</span>
|
<span class="status-badge @GetStatusClass(session.Status)">@TranslateStatus(session.Status)</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="@session.JoinLink" target="_blank" rel="noopener noreferrer"
|
<a href="@session.JoinLink" target="_blank" rel="noopener noreferrer" class="session-join-link">
|
||||||
style="max-width: 150px; display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
|
|
||||||
Подключиться ↗
|
Подключиться ↗
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
<div class="session-table-actions">
|
||||||
<a href="/session/edit/@session.Id" class="btn-gm btn-gm-outline" style="font-size: 0.8125rem; padding: 0.375rem 0.75rem;">
|
<a href="/session/edit/@session.Id" class="btn-gm btn-gm-outline">
|
||||||
✏️ Изменить
|
✏️ Изменить
|
||||||
</a>
|
</a>
|
||||||
@if (CanPromote(session))
|
@if (CanPromote(session))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn-gm btn-gm-success" style="font-size: 0.8125rem; padding: 0.375rem 0.75rem;" disabled="@(promotingSessionId == session.Id)" @onclick="() => PromoteWaitlisted(session.Id)">
|
<button type="button" class="btn-gm btn-gm-success" disabled="@(promotingSessionId == session.Id)" @onclick="() => PromoteWaitlisted(session.Id)">
|
||||||
@(promotingSessionId == session.Id ? "⏳ Поднимаем..." : "⬆️ Из ожидания")
|
@(promotingSessionId == session.Id ? "⏳ Поднимаем..." : "⬆️ Из ожидания")
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|||||||
+101
-51
@@ -1,5 +1,5 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
GM-Relay Design System v1.9.4
|
GM-Relay Design System v1.9.5
|
||||||
Dark RPG Dashboard Theme
|
Dark RPG Dashboard Theme
|
||||||
============================================ */
|
============================================ */
|
||||||
|
|
||||||
@@ -422,6 +422,46 @@ select option {
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.session-table-desktop {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-table-desktop-card {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-table-desktop .gm-table {
|
||||||
|
min-width: 760px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-table-desktop .gm-table th:last-child,
|
||||||
|
.session-table-desktop .gm-table td:last-child {
|
||||||
|
width: 8.5rem;
|
||||||
|
min-width: 8.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-join-link {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-table-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-table-actions .btn-gm {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
/* === Alerts === */
|
/* === Alerts === */
|
||||||
.gm-alert {
|
.gm-alert {
|
||||||
padding: 0.875rem 1.125rem;
|
padding: 0.875rem 1.125rem;
|
||||||
@@ -918,7 +958,64 @@ body.telegram-mini-app .content {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
body.telegram-mini-app .session-table-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.telegram-mini-app .session-card-mobile {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card {
|
||||||
|
background: var(--glass-bg);
|
||||||
|
backdrop-filter: blur(var(--glass-blur));
|
||||||
|
border: 1px solid var(--glass-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: 1rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
transition: all var(--transition-smooth);
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card:hover {
|
||||||
|
border-color: var(--border-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-actions {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
.session-table-desktop {
|
.session-table-desktop {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -926,56 +1023,9 @@ body.telegram-mini-app .content {
|
|||||||
.session-card-mobile {
|
.session-card-mobile {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.session-card {
|
@media (max-width: 768px) {
|
||||||
background: var(--glass-bg);
|
|
||||||
backdrop-filter: blur(var(--glass-blur));
|
|
||||||
border: 1px solid var(--glass-border);
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
padding: 1rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
transition: all var(--transition-smooth);
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card:hover {
|
|
||||||
border-color: var(--border-glow);
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card-title {
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.9375rem;
|
|
||||||
color: var(--text-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5rem;
|
|
||||||
font-size: 0.8125rem;
|
|
||||||
color: var(--text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card-row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.session-card-actions {
|
|
||||||
margin-top: 0.75rem;
|
|
||||||
padding-top: 0.75rem;
|
|
||||||
border-top: 1px solid var(--border-color);
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-grid {
|
.card-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,56 @@ public sealed class WebStylesTests
|
|||||||
Assert.Contains(".telegram-mini-app .nav-toggle", appCss, StringComparison.Ordinal);
|
Assert.Contains(".telegram-mini-app .nav-toggle", appCss, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AppCss_ShouldKeepDesktopSessionActionsReadableWhenTableOverflows()
|
||||||
|
{
|
||||||
|
var appCss = await File.ReadAllTextAsync(FindRepositoryFile("src/GmRelay.Web/wwwroot/app.css"));
|
||||||
|
|
||||||
|
Assert.Matches(
|
||||||
|
@"\.session-table-desktop\s*\{[\s\S]*overflow-x:\s*auto;",
|
||||||
|
appCss);
|
||||||
|
Assert.Matches(
|
||||||
|
@"\.session-table-desktop\s+\.gm-table\s*\{[\s\S]*min-width:\s*760px;",
|
||||||
|
appCss);
|
||||||
|
Assert.Matches(
|
||||||
|
@"\.session-table-actions\s+\.btn-gm\s*\{[\s\S]*white-space:\s*nowrap;",
|
||||||
|
appCss);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AppCss_ShouldUseCardSessionLayoutInsideTelegramMiniApp()
|
||||||
|
{
|
||||||
|
var appCss = await File.ReadAllTextAsync(FindRepositoryFile("src/GmRelay.Web/wwwroot/app.css"));
|
||||||
|
|
||||||
|
Assert.Matches(
|
||||||
|
@"body\.telegram-mini-app\s+\.session-table-desktop\s*\{[\s\S]*display:\s*none;",
|
||||||
|
appCss);
|
||||||
|
Assert.Matches(
|
||||||
|
@"body\.telegram-mini-app\s+\.session-card-mobile\s*\{[\s\S]*display:\s*block;",
|
||||||
|
appCss);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AppCss_ShouldUseCardSessionLayoutWhenDesktopSidebarLeavesNarrowContent()
|
||||||
|
{
|
||||||
|
var appCss = await File.ReadAllTextAsync(FindRepositoryFile("src/GmRelay.Web/wwwroot/app.css"));
|
||||||
|
|
||||||
|
Assert.Matches(
|
||||||
|
@"@media\s*\(max-width:\s*1024px\)\s*\{[\s\S]*\.session-table-desktop\s*\{[\s\S]*display:\s*none;[\s\S]*\.session-card-mobile\s*\{[\s\S]*display:\s*block;",
|
||||||
|
appCss);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GroupDetailsPage_ShouldUseSessionTableLayoutClasses()
|
||||||
|
{
|
||||||
|
var groupDetailsPage = await File.ReadAllTextAsync(FindRepositoryFile("src/GmRelay.Web/Components/Pages/GroupDetails.razor"));
|
||||||
|
|
||||||
|
Assert.Contains("session-table-desktop-card", groupDetailsPage, StringComparison.Ordinal);
|
||||||
|
Assert.Contains("session-table-actions", groupDetailsPage, StringComparison.Ordinal);
|
||||||
|
Assert.Contains("session-join-link", groupDetailsPage, StringComparison.Ordinal);
|
||||||
|
Assert.DoesNotContain("overflow: hidden", groupDetailsPage, StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
private static string FindRepositoryFile(string relativePath)
|
private static string FindRepositoryFile(string relativePath)
|
||||||
{
|
{
|
||||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||||
|
|||||||
Reference in New Issue
Block a user