167 lines
5.5 KiB
Plaintext
167 lines
5.5 KiB
Plaintext
@page "/articles/search"
|
|
@page "/articles/search/{SearchTerms}"
|
|
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using Microsoft.Extensions.Logging
|
|
@using MudBlazor
|
|
@using OpenArchival.DataAccess
|
|
@using System.Linq
|
|
@using System.Text.RegularExpressions
|
|
@using System.Net
|
|
|
|
<BlogPostSearchBar @ref="_searchBar"
|
|
@bind-SelectedFilter="_selectedFilter"
|
|
SearchTermsChanged="PerformSearchAsyncCallback" />
|
|
@{
|
|
if (_showMostRecent && PostSearch.TotalResults > 0)
|
|
{
|
|
<MudGrid Justify="Justify.FlexStart" Class="mt-1 ml-1 mb-2">
|
|
<MudText Typo="Typo.h6" Color="Color.Primary">Most Recent Posts:</MudText>
|
|
</MudGrid>
|
|
}
|
|
else if (PostSearch.TotalResults > 0)
|
|
{
|
|
<MudGrid Justify="Justify.FlexStart" Class="mt-1 ml-1 mb-2">
|
|
<MudText Typo="Typo.subtitle2" Class="my-2">@PostSearch.TotalResults results found</MudText>
|
|
<MudButton Class="ml-1" StartIcon="@Icons.Material.Filled.Clear" OnClick="OnClearResults" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small">Clear</MudButton>
|
|
</MudGrid>
|
|
}
|
|
}
|
|
|
|
@if (PostSearch.SearchResults.Count > 0)
|
|
{
|
|
<MudGrid>
|
|
@foreach (var post in PostSearch.SearchResults)
|
|
{
|
|
<MudItem xs="12" sm="6" md="4" lg="4">
|
|
<MudLink Href="@($"/articles/{post.Id}")" Target="_blank" Style="text-decoration: none; color: inherit;">
|
|
<MudCard Style="@($"height: {Math.Floor(400 * 0.7)}px; display: flex; flex-direction: column;")">
|
|
|
|
@if (post.MainPhoto != null)
|
|
{
|
|
<MudCardMedia Image="@($"/api/files/{post.MainPhoto.Id}")" Style="height: 100%;" />
|
|
}
|
|
else
|
|
{
|
|
<MudCardMedia Image="/images/placeholder.png" Style="height: 100%;" /> }
|
|
|
|
<MudCardContent Style=@($"flex-grow: 1; overflow-y: clip; height:{Math.Floor(400 * 0.3)}px;")>
|
|
<MudText Typo="Typo.h5">@post.Title</MudText>
|
|
<MudText Typo="Typo.body2">@CreateContentSnippet(post.Content)</MudText>
|
|
</MudCardContent>
|
|
</MudCard>
|
|
</MudLink>
|
|
</MudItem>
|
|
}
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="d-flex justify-center py-2 mt-4" Elevation="0">
|
|
<MudPagination Count="PostSearch.TotalPages"
|
|
Selected="PostSearch.CurrentPage"
|
|
SelectedChanged="OnPageChangedAsync" />
|
|
</MudPaper>
|
|
}
|
|
|
|
@inject IDbContextFactory<ApplicationDbContext> ContextFactory;
|
|
@inject ILogger<SearchBlog> Logger;
|
|
@inject NavigationManager NavigationManager;
|
|
@inject BlogPostSearch PostSearch;
|
|
|
|
@code {
|
|
[Parameter]
|
|
public string SearchTerms { get; set; } = "";
|
|
|
|
private BlogSearchFilterType _selectedFilter = BlogSearchFilterType.All;
|
|
private BlogPostSearchBar _searchBar = default!;
|
|
|
|
// List for the "no results" slider display
|
|
private List<SearchPageSliderEntry> _sliderEntries { get; set; } = [];
|
|
|
|
private bool _showMostRecent = true;
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
// This runs when the page loads, checking for search terms in the URL
|
|
if (string.IsNullOrWhiteSpace(SearchTerms))
|
|
{
|
|
await PostSearch.Search("", _selectedFilter, 1);
|
|
_showMostRecent = true;
|
|
}
|
|
else
|
|
{
|
|
await PostSearch.Search(SearchTerms, _selectedFilter, 1);
|
|
_showMostRecent = false;
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is called by the SearchBar component's 'SearchTermsChanged' event.
|
|
/// </summary>
|
|
private async Task PerformSearchAsyncCallback(string searchTerms)
|
|
{
|
|
if (string.IsNullOrEmpty(searchTerms))
|
|
{
|
|
_showMostRecent = true;
|
|
} else
|
|
{
|
|
_showMostRecent = false;
|
|
}
|
|
|
|
SearchTerms = searchTerms; // Update the page's parameter
|
|
|
|
// Update the URL to reflect the new search
|
|
NavigationManager.NavigateTo($"/articles/search/{Uri.EscapeDataString(searchTerms)}", replace: true);
|
|
|
|
// Perform the search (always start on page 1)
|
|
await PostSearch.Search(searchTerms, _selectedFilter, 1);
|
|
|
|
StateHasChanged(); // Re-render the page with results
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is called by the MudPagination's 'SelectedChanged' event.
|
|
/// </summary>
|
|
private async Task OnPageChangedAsync(int page)
|
|
{
|
|
// Load the specific page using the service
|
|
await PostSearch.LoadPageAsync(page);
|
|
StateHasChanged(); // Re-render with the new page's data
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the search results and state.
|
|
/// </summary>
|
|
private void OnClearResults()
|
|
{
|
|
PostSearch.ClearResults();
|
|
SearchTerms = "";
|
|
|
|
// Navigate back to the base search page
|
|
NavigationManager.NavigateTo("/articles/search", replace: true);
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
public static string CreateContentSnippet(string html, int maxLength = 150)
|
|
{
|
|
if (string.IsNullOrEmpty(html))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
// Strip HTML tags
|
|
string plainText = Regex.Replace(html, @"<[^>]+>", string.Empty);
|
|
|
|
// Decode HTML entities
|
|
plainText = WebUtility.HtmlDecode(plainText).Trim();
|
|
|
|
if (plainText.Length > maxLength)
|
|
{
|
|
return plainText.Substring(0, maxLength) + "...";
|
|
}
|
|
|
|
return plainText;
|
|
}
|
|
}
|