...vibing keyboard improvements

This commit is contained in:
2026-06-17 22:28:49 -04:00
parent 512f739d4c
commit 1ab018591d
3 changed files with 139 additions and 52 deletions
+104 -48
View File
@@ -2,6 +2,16 @@
<PageTitle>Keyboard</PageTitle>
<div class="character-selector">
<label>Character:</label>
<select @bind="selectedCharacter" @bind:after="RebuildKeyboardData">
@foreach (var c in Characters)
{
<option value="@c">@c</option>
}
</select>
</div>
<div class="keyboard-container" @onkeydown="HandleKeyDown" tabindex="0" @ref="containerRef">
<div class="keyboard-wrapper">
<div class="kb-row">
@@ -257,6 +267,8 @@
private List<KeyData> ShiftKeys { get; set; } = new();
private KeyData spaceKey = null!;
private KeyData shiftSpaceKey = null!;
private string selectedCharacter = "Xavian";
private List<string> Characters = [];
public class KeyData
{
@@ -291,57 +303,100 @@
protected override void OnInitialized()
{
Keys = new List<KeyData>
{
new() { Id = "1", Label = "1", SkillName = "Aura of Solace", Character = "Xavian", CooldownDuration = 3 },
new() { Id = "2", Label = "2" },
new() { Id = "3", Label = "3" },
new() { Id = "4", Label = "4" },
new() { Id = "5", Label = "5" },
new() { Id = "6", Label = "6" },
new() { Id = "q", Label = "Q", SkillName = "Shinning Halo", Character = "Xavian", CooldownDuration = 30 },
new() { Id = "w", Label = "W", SkillName = "Brilliant Flash", Character = "Xavian", CooldownDuration = 0 },
new() { Id = "e", Label = "E", SkillName = "Move Forward" },
new() { Id = "r", Label = "R", SkillName = "Sun Strike", Character = "Xavian", CooldownDuration = 0 },
new() { Id = "t", Label = "T", SkillName = "Sky Crash", Character = "Xavian", CooldownDuration = 60 },
new() { Id = "a", Label = "A", SkillName = "Solar Shield", Character = "Xavian", CooldownDuration = 15 },
new() { Id = "s", Label = "S", SkillName = "Move Left" },
new() { Id = "d", Label = "D", SkillName = "Move Back" },
new() { Id = "f", Label = "F", SkillName = "Move Right" },
new() { Id = "g", Label = "G", SkillName = "Blinding Slash", Character = "Xavian", CooldownDuration = 6 },
new() { Id = "z", Label = "Z" },
new() { Id = "x", Label = "X" },
new() { Id = "c", Label = "C" },
new() { Id = "v", Label = "V", SkillName = "Interupt", Character = "Xavian", CooldownDuration = 12 },
new() { Id = "b", Label = "B", SkillName = "Taunt", Character = "Xavian", CooldownDuration = 8 }
};
spaceKey = new KeyData { Id = "space", Label = "Space", SkillName = "Jump", CooldownDuration = 0.5 };
Characters = DocsData.All
.OfType<SkillDoc>()
.Where(s => s.Character != null)
.Select(s => s.Character!)
.Distinct()
.Order()
.ToList();
ShiftKeys = new List<KeyData>
if (Characters.Count == 0) Characters.Add("Xavian");
RebuildKeyboardData();
}
private void RebuildKeyboardData()
{
var skillByKey = DocsData.All
.OfType<SkillDoc>()
.Where(s => !string.IsNullOrEmpty(s.Key) && s.Character == selectedCharacter)
.GroupBy(s => s.Key!)
.ToDictionary(g => g.Key, g =>
g.OrderBy(s => string.IsNullOrEmpty(s.CostSwiftReprieval) ? 0 : 1).First());
var actionByKey = DocsData.All
.OfType<KeyDoc>()
.Where(k => !string.IsNullOrEmpty(k.Action))
.Select(k => new
{
Key = Path.GetFileNameWithoutExtension(k.FileName),
k.Action
})
.GroupBy(x => x.Key)
.ToDictionary(g => g.Key, g => g.First().Action!, StringComparer.OrdinalIgnoreCase);
var keyLabels = new[] { "1", "2", "3", "4", "5", "6", "Q", "W", "E", "R", "T", "A", "S", "D", "F", "G", "Z", "X", "C", "V", "B" };
Keys = keyLabels.Select(label =>
{
new() { Id = "shift-1", Label = "Shift+1" },
new() { Id = "shift-2", Label = "Shift+2" },
new() { Id = "shift-3", Label = "Shift+3" },
new() { Id = "shift-4", Label = "Shift+4" },
new() { Id = "shift-5", Label = "Shift+5" },
new() { Id = "shift-6", Label = "Shift+6" },
new() { Id = "shift-q", Label = "Shift+Q", SkillName = "Decree of the Sun", Character = "Xavian", CooldownDuration = 0 },
new() { Id = "shift-w", Label = "Shift+W" },
new() { Id = "shift-e", Label = "Shift+E" },
new() { Id = "shift-r", Label = "Shift+R", SkillName = "Omnistrike", Character = "Xavian", CooldownDuration = 18 },
new() { Id = "shift-t", Label = "Shift+T" },
new() { Id = "shift-a", Label = "Shift+A" },
new() { Id = "shift-s", Label = "Shift+S" },
new() { Id = "shift-d", Label = "Shift+D" },
new() { Id = "shift-f", Label = "Shift+F" },
new() { Id = "shift-g", Label = "Shift+G", SkillName = "Solar Blades", Character = "Xavian", CooldownDuration = 9 },
new() { Id = "shift-z", Label = "Shift+Z" },
new() { Id = "shift-x", Label = "Shift+X" },
new() { Id = "shift-c", Label = "Shift+C" },
new() { Id = "shift-v", Label = "Shift+V" },
new() { Id = "shift-b", Label = "Shift+B" }
var skill = skillByKey.GetValueOrDefault(label);
var action = actionByKey.GetValueOrDefault(label);
var skillName = skill != null ? Path.GetFileNameWithoutExtension(skill.FileName) : action;
return new KeyData
{
Id = label.ToLower(),
Label = label,
SkillName = skillName,
Character = skill?.Character,
CooldownDuration = ParseCooldown(skill?.Cooldown)
};
}).ToList();
var spaceSkill = skillByKey.GetValueOrDefault(" ");
var spaceAction = actionByKey.GetValueOrDefault("Space");
spaceKey = new KeyData
{
Id = "space",
Label = "Space",
SkillName = spaceSkill != null ? Path.GetFileNameWithoutExtension(spaceSkill.FileName) : spaceAction,
Character = spaceSkill?.Character,
CooldownDuration = ParseCooldown(spaceSkill?.Cooldown)
};
shiftSpaceKey = new KeyData { Id = "shift-space", Label = "Shift+Space" };
ShiftKeys = keyLabels.Select(label =>
{
var shiftKeyStr = "Shift + " + label;
var skill = skillByKey.GetValueOrDefault(shiftKeyStr);
var action = actionByKey.GetValueOrDefault(shiftKeyStr);
var skillName = skill != null ? Path.GetFileNameWithoutExtension(skill.FileName) : action;
return new KeyData
{
Id = "shift-" + label.ToLower(),
Label = "Shift+" + label,
SkillName = skillName,
Character = skill?.Character,
CooldownDuration = ParseCooldown(skill?.Cooldown)
};
}).ToList();
var shiftSpaceSkill = skillByKey.GetValueOrDefault("Shift + Space");
var shiftSpaceAction = actionByKey.GetValueOrDefault("Shift + Space");
shiftSpaceKey = new KeyData
{
Id = "shift-space",
Label = "Shift+Space",
SkillName = shiftSpaceSkill != null ? Path.GetFileNameWithoutExtension(shiftSpaceSkill.FileName) : shiftSpaceAction,
Character = shiftSpaceSkill?.Character,
CooldownDuration = ParseCooldown(shiftSpaceSkill?.Cooldown)
};
}
private static double ParseCooldown(string? cooldown)
{
if (string.IsNullOrEmpty(cooldown)) return 0;
if (double.TryParse(cooldown, out var result)) return result;
return 0;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
@@ -385,6 +440,7 @@
private void ActivateKey(KeyData key)
{
if (key.OnCooldown) return;
if (key.Character == null) return;
var duration = key.CooldownDuration > 0 ? key.CooldownDuration : 0.5;
key.Remaining = duration;
+35
View File
@@ -120,6 +120,41 @@
text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
}
.character-selector {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
padding: 10px 20px;
background: #1a1a1a;
border: 1px solid #2a2a2a;
border-radius: 8px;
}
.character-selector label {
font-size: 13px;
font-weight: 600;
color: #888;
text-transform: uppercase;
letter-spacing: 0.8px;
}
.character-selector select {
padding: 6px 12px;
border: 1px solid #333;
border-radius: 6px;
background: #0f0f0f;
color: #e0e0e0;
font-size: 14px;
outline: none;
cursor: pointer;
}
.character-selector select:focus {
border-color: #5588ff;
box-shadow: 0 0 0 3px rgba(85, 136, 255, 0.15);
}
.kb-divider {
color: #888;
font-size: 14px;