diff --git a/Iceshrimp.Frontend/Components/SettingsMenu.razor b/Iceshrimp.Frontend/Components/SettingsMenu.razor index b627bb63..01a43f62 100644 --- a/Iceshrimp.Frontend/Components/SettingsMenu.razor +++ b/Iceshrimp.Frontend/Components/SettingsMenu.razor @@ -16,6 +16,12 @@ @Loc["About"] + + + + @Loc["Filters"] + + @code { diff --git a/Iceshrimp.Frontend/Pages/Settings/Filters.razor b/Iceshrimp.Frontend/Pages/Settings/Filters.razor new file mode 100644 index 00000000..ad5583c5 --- /dev/null +++ b/Iceshrimp.Frontend/Pages/Settings/Filters.razor @@ -0,0 +1,290 @@ +@page "/settings/filters" +@using Iceshrimp.Frontend.Core.Miscellaneous +@using Iceshrimp.Frontend.Components +@using Iceshrimp.Frontend.Core.Services +@using Iceshrimp.Frontend.Localization +@using Iceshrimp.Shared.Schemas.Web +@using Microsoft.Extensions.Localization +@using Iceshrimp.Assets.PhosphorIcons +@using Microsoft.Extensions.Logging +@* @layout SettingsLayout *@ +@inject ApiService Api; +@inject ILogger Logger; +@inject IStringLocalizer Loc; + + + @if (State is State.Loaded) + { + + @foreach (var el in FilterList) + { + + + @Loc["Name"] + @el.Name + + + @Loc["Expiry"] + @el.Expiry.ToString() + + + @Loc["Keywords"] + @foreach (var keyword in el.Keywords) + { + @keyword + } + + + @Loc["Action"] + @el.Action.ToString() + + + @Loc["Contexts"] + @foreach (var context in el.Contexts) + { + @context + } + + + DeleteFilter(el.Id)">@Loc["Delete"] + } + + + + + @Loc["Filter Name"] + @if (_filterNameInvalid) + { + @Loc["Filter name is required"] + } + + + + + @Loc["Keywords"] + + @if (_filterKeywordsInvalid) + { + @Loc["At least 1 keyword is required"] + } + @foreach (var el in FilterKeywords) + { + + @el + FilterKeywords.Remove(el)"> + + + + } + + @Loc["Add"] + + + @Loc["Filter Action"] + + @if (FilterAction == FilterResponse.FilterAction.Hide) + { + + @Loc["Hide"] + } + @if (FilterAction == FilterResponse.FilterAction.Warn) + { + + @Loc["Warn"] + } + + + @Loc["Hide"] + + + @Loc["Warn"] + + + + + + @Loc["Filter Contexts"] + @if (_filterContextsInvalid) + { + @Loc["At least 1 context required"] + } + + @foreach (var el in FilterContexts) + { + + @el + FilterContexts.Remove(el)"> + + + + } + + + @Loc["Add Filter Context"] + + + @Loc["Home"] + + + @Loc["Lists"] + + + @Loc["Threads"] + + + @Loc["Notifications"] + + + @Loc["Accounts"] + + + @Loc["Public"] + + + + + + + @if (_filterExpiryInvalid) + { + @Loc["Expiry is required"] + } + @Loc["Filter Expiry"] + + + + @Loc["Add Filter"] + @Loc["Add Filter"] + + + + + @Loc["Error"] + + + + } + + +@code { + private List FilterList { get; set; } = []; + private State State { get; set; } = State.Loading; + private string FilterName { get; set; } = ""; + private string Keyword { get; set; } = ""; + private List FilterKeywords { get; set; } = []; + private DateTime? FilterExpiry { get; set; } + private FilterResponse.FilterAction FilterAction { get; set; } + private Menu MenuFilterAction { get; set; } = null!; + private Menu MenuFilterContexts { get; set; } = null!; + private List FilterContexts { get; set; } = []; + private StateButton ButtonAddFilter { get; set; } = null!; + private bool _filterNameInvalid = false; + private bool _filterKeywordsInvalid = false; + private bool _filterExpiryInvalid = false; + private bool _filterContextsInvalid = false; + + protected override async Task OnInitializedAsync() + { + try + { + FilterList = (List)await Api.Filters.GetFilters(); + State = State.Loaded; + } + catch (ApiException) + { + State = State.Error; + } + } + + private async Task DeleteFilter(long id) + { + try + { + var res = await Api.Filters.DeleteFilter(id); + if (res == true) + { + var index = FilterList.FindIndex(p => p.Id == id); + FilterList.RemoveAt(index); + } + } + catch (ApiException) + { + + } + } + + private async Task TryAddFilter() + { + bool valid = true; + + if (FilterName.Length < 1) + { + _filterNameInvalid = true; + valid = false; + } + + if (FilterKeywords.Count < 1) + { + _filterKeywordsInvalid = true; + valid = false; + } + + if (FilterExpiry == null) + { + _filterExpiryInvalid = true; + valid = false; + } + + if (FilterContexts.Count < 1) + { + _filterContextsInvalid = true; + valid = false; + } + + if (valid) + { + if (FilterExpiry is not null) + { + FilterExpiry = new DateTimeOffset((DateTime)FilterExpiry, DateTimeOffset.Now.Offset).UtcDateTime; + } + + var newFilterRequest = new FilterRequest + { + Name = FilterName, + Expiry = FilterExpiry, + Keywords = FilterKeywords, + Action = FilterAction, + Contexts = FilterContexts + }; + try + { + var filter = await Api.Filters.CreateFilter(newFilterRequest); + } + catch (ApiException) { } + } + } + + private void ToggleMenu() + { + MenuFilterAction.Toggle(); + } + + private void ToggleFilterContextMenu() + { + MenuFilterContexts.Toggle(); + } + + private void AddKeyword() + { + if (Keyword.Length >= 1) + FilterKeywords.Add(Keyword); + } + + private void AddFilterContext(FilterResponse.FilterContext context) + { + if (FilterContexts.Contains(context) == false) + { + FilterContexts.Add(context); + } + } +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Pages/Settings/Filters.razor.css b/Iceshrimp.Frontend/Pages/Settings/Filters.razor.css new file mode 100644 index 00000000..2bdf659e --- /dev/null +++ b/Iceshrimp.Frontend/Pages/Settings/Filters.razor.css @@ -0,0 +1,21 @@ +.positioned { + position: relative; + top: 0; +} + +h3 { + margin-top: 0.25rem; + font-size: 0.8rem; +} + +.filter { + border: var(--highlight-color) solid 0.1rem; +} + +.creature-input:invalid { + border-color: red; +} + +.name-input:invalid { + border-color: red; +} \ No newline at end of file