Fan website of IMMORTAL: Gates of Pyre.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

208 lines
5.0 KiB

@using System.Timers
@implements IDisposable;
@inject ISearchService searchService
@inject IJSRuntime jsRuntime
@inject NavigationManager navigationManager
@if (searchService.IsLoaded() && searchService.IsVisible)
{
<div id="searchBackground" class="searchBackground" onclick="@CloseDialog">
<div class="searchContainer"
@onclick:preventDefault="true"
@onclick:stopPropagation="true">
<FormLayoutComponent>
<FormTextComponent OnFocus="OnFocus" Id="searchInput" Placeholder="Search..." OnInput="SearchChanged"></FormTextComponent>
</FormLayoutComponent>
<div class="searchBox">
@if (SearchText.Length > 0)
{
foreach (var searchSection in searchService.Searches)
{
var searchPoints = searchSection.Value.FindAll(x => x.Title.ToLower().Contains(SearchText.ToLower()));
@if (searchPoints.Count > 0)
{
<div>
<div class="searchSectionTitle">
@searchSection.Key
</div>
<div class="searchContents">
@foreach (var searchPoint in searchPoints)
{
<div>
<button class="searchLink @searchPoint.PointType.ToLower()"
label="@searchPoint.Title"
@onclick="() => OnSearch(searchPoint)">
@searchPoint.Title
</button>
@if (!searchPoint.Summary.Trim().Equals(""))
{
<i> - @searchPoint.Summary</i>
}
</div>
}
</div>
</div>
}
}
}
</div>
</div>
</div>
<style>
.pageContents * {
filter: blur(2px);
}
.searchBackground {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
}
.searchBox {
padding: 12px;
overflow-y: scroll;
overflow-x: hidden;
height: 530px;
border: 1px solid black;
border-radius: 2px;
}
.searchContents {
display: flex;
flex-direction: column;
gap: 6px;
align-items: flex-start;
padding: 12px;
}
.searchSectionTitle {
font-weight: bolder;
}
.searchContainer {
margin-left: auto;
margin-right: auto;
margin-top: 64px;
width: 800px;
height: 600px;
background-color: var(--background);
border-width: var(--dialog-border-width);
border-style: solid;
border-color: var(--dialog-border-color);
border-radius: var(--dialog-radius);
padding: 8px;
box-shadow: 1px 2px 2px black;
}
.searchLink {
text-decoration: underline;
}
@@media only screen and (max-width: 1025px) {
.searchContainer {
height: 300px;
}
.searchBox {
height: 230px;
}
}
</style>
}
@code {
private ElementReference searchBox;
private string SearchText { get; set; } = "";
protected override void OnInitialized()
{
searchService.Subscribe(OnSearchChanged);
timer = new Timer(200);
timer.Elapsed += FocusTimer;
timer.Enabled = false;
}
private void FocusTimer(object? sender, ElapsedEventArgs e)
{
jsRuntime.InvokeVoidAsync("SetFocusToElement", "searchInput");
StateHasChanged();
}
private Timer timer = null!;
private void OnSearchChanged()
{
if (timer.Enabled != searchService.IsVisible)
{
timer.Enabled = searchService.IsVisible;
}
StateHasChanged();
}
public void Dispose()
{
searchService.Unsubscribe(OnSearchChanged);
timer.Elapsed -= FocusTimer;
}
public void CloseDialog()
{
searchService.Hide();
}
public void NavigateTo(string url)
{
if (url.Contains("#"))
{
navigationManager.NavigateTo(url,
navigationManager.Uri.Split("#").First().Contains(url.Split("#").First()));
}
else
{
navigationManager.NavigateTo(url);
}
}
private void SearchChanged(ChangeEventArgs obj)
{
SearchText = obj.Value!.ToString()!;
}
private void OnSearch(SearchPointModel searchPoint)
{
NavigateTo(searchPoint.Href);
searchService.Hide();
}
private void OnFocus(object obj)
{
timer.Enabled = false;
}
}