[sln] Code cleanup

This commit is contained in:
Laura Hausmann 2024-09-13 21:21:52 +02:00
parent 28b57e35a3
commit afe62b0aab
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
95 changed files with 580 additions and 523 deletions

View file

@ -16,7 +16,11 @@ namespace Iceshrimp.Backend.Controllers.Federation;
[Route("/nodeinfo")]
[EnableCors("well-known")]
[Produces(MediaTypeNames.Application.Json)]
public class NodeInfoController(IOptions<Config.InstanceSection> instanceConfig, IOptions<Config.StorageSection> storageConfig, DatabaseContext db) : ControllerBase
public class NodeInfoController(
IOptions<Config.InstanceSection> instanceConfig,
IOptions<Config.StorageSection> storageConfig,
DatabaseContext db
) : ControllerBase
{
[HttpGet("2.1")]
[HttpGet("2.0")]
@ -92,30 +96,30 @@ public class NodeInfoController(IOptions<Config.InstanceSection> instanceConfig,
EnableGithubIntegration = false,
EnableDiscordIntegration = false,
EnableEmail = false,
PublicTimelineVisibility = new() {
PublicTimelineVisibility = new NodeInfoResponse.PleromaPublicTimelineVisibility
{
Bubble = false,
Federated = false,
Local = false,
Local = false
},
UploadLimits = new() {
// @formatter:off
UploadLimits = new NodeInfoResponse.PleromaUploadLimits
{
General = maxUploadSize,
Avatar = maxUploadSize,
Background = maxUploadSize,
Banner = maxUploadSize,
Banner = maxUploadSize
},
Suggestions = new() {
Enabled = false
},
Federation = new() {
Enabled = true
}
// @formatter:on
Suggestions = new NodeInfoResponse.PleromaSuggestions { Enabled = false },
Federation = new NodeInfoResponse.PleromaFederation { Enabled = true }
},
OpenRegistrations = false
};
}
[HttpGet("2.0.json")]
public IActionResult GetNodeInfoAkkoFE()
public IActionResult GetNodeInfoAkkoma()
{
return Redirect("/nodeinfo/2.0");
}

View file

@ -96,7 +96,7 @@ public class ConversationsController(
var user = HttpContext.GetUserOrFail();
var conversation = await db.Conversations(user)
.IncludeCommonProperties()
.Where(p => (p.ThreadIdOrId) == id)
.Where(p => p.ThreadIdOrId == id)
.Select(p => new Conversation
{
Id = p.ThreadIdOrId,

View file

@ -3,6 +3,7 @@ using System.Net.Mime;
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Shared.Attributes;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database;
@ -33,15 +34,14 @@ public class InstanceController(DatabaseContext db, MetaService meta) : Controll
var (instanceName, instanceDescription, adminContact) =
await meta.GetMany(MetaEntity.InstanceName, MetaEntity.InstanceDescription, MetaEntity.AdminContactEmail);
var vapidKey = await meta.Get(MetaEntity.VapidPublicKey); // can't merge with above call since they're all nullable and this is not.
// can't merge with above call since they're all nullable and this is not.
var vapidKey = await meta.Get(MetaEntity.VapidPublicKey);
return new InstanceInfoV1Response(config.Value, instanceName, instanceDescription, adminContact)
{
Stats = new InstanceStats(userCount, noteCount, instanceCount),
Pleroma = new() {
VapidPublicKey = vapidKey,
Metadata = new(),
}
Pleroma = new PleromaInstanceExtensions { VapidPublicKey = vapidKey, Metadata = new InstanceMetadata() }
};
}

View file

@ -76,7 +76,7 @@ public class NotificationController(DatabaseContext db, NotificationRenderer not
.FirstOrDefaultAsync() ??
throw GracefulException.RecordNotFound();
var res = await notificationRenderer.RenderAsync(notification.EnforceRenoteReplyVisibility(p => p.Note), user, isPleroma);
return res;
return await notificationRenderer.RenderAsync(notification.EnforceRenoteReplyVisibility(p => p.Note),
user, isPleroma);
}
}

View file

@ -1,4 +1,5 @@
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
@ -162,10 +163,7 @@ public class NoteRenderer(
Poll = poll,
Reactions = reactions,
Filtered = filterResult,
Pleroma = new() {
Reactions = reactions,
ConversationId = note.ThreadIdOrId
}
Pleroma = new PleromaStatusExtensions { Reactions = reactions, ConversationId = note.ThreadIdOrId }
};
return res;
@ -321,7 +319,11 @@ public class NoteRenderer(
db.NoteReactions.Any(i => i.NoteId == p.First().NoteId &&
i.Reaction == p.First().Reaction &&
i.User == user),
AccountIds = db.NoteReactions.Where(i => i.NoteId == p.First().NoteId && p.Select(r => r.Id).Contains(i.Id)).Select(i => i.UserId).ToList()
AccountIds = db.NoteReactions
.Where(i => i.NoteId == p.First().NoteId &&
p.Select(r => r.Id).Contains(i.Id))
.Select(i => i.UserId)
.ToList()
})
.ToListAsync();

View file

@ -1,4 +1,5 @@
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions;
@ -29,7 +30,8 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
await userRenderer.RenderAsync(dbNotifier);
string? emojiUrl = null;
if (notification.Reaction != null) {
if (notification.Reaction != null)
{
// explicitly check to skip another database call if url is actually null
if (emojiUrls != null)
{
@ -38,7 +40,10 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
else if (EmojiService.IsCustomEmoji(notification.Reaction))
{
var parts = notification.Reaction.Trim(':').Split('@');
emojiUrl = await db.Emojis.Where(e => e.Name == parts[0] && e.Host == (parts.Length > 1 ? parts[1] : null)).Select(e => e.PublicUrl).FirstOrDefaultAsync();
emojiUrl = await db.Emojis
.Where(e => e.Name == parts[0] && e.Host == (parts.Length > 1 ? parts[1] : null))
.Select(e => e.PublicUrl)
.FirstOrDefaultAsync();
}
}
@ -51,9 +56,7 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
CreatedAt = notification.CreatedAt.ToStringIso8601Like(),
Emoji = notification.Reaction,
EmojiUrl = emojiUrl,
Pleroma = new() {
IsSeen = notification.IsRead
}
Pleroma = new PleromaNotificationExtensions { IsSeen = notification.IsRead }
};
return res;
@ -85,20 +88,28 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
.DistinctBy(p => p.Id),
user, Filter.FilterContext.Notifications, accounts);
var parts = notifications.Where(p => p.Reaction != null && EmojiService.IsCustomEmoji(p.Reaction)).Select(p => {
var parts = notificationList.Where(p => p.Reaction != null && EmojiService.IsCustomEmoji(p.Reaction))
.Select(p =>
{
var parts = p.Reaction!.Trim(':').Split('@');
return new { Name = parts[0], Host = parts.Length > 1 ? parts[1] : null };
});
// https://github.com/dotnet/efcore/issues/31492
//TODO: is there a better way of expressing this using LINQ?
IQueryable<Emoji> urlQ = db.Emojis;
foreach (var part in parts)
urlQ = urlQ.Concat(db.Emojis.Where(e => e.Name == part.Name && e.Host == part.Host));
var emojiUrls = (await urlQ
.Select(e => new { Name = $":{e.Name}{(e.Host != null ? "@" + e.Host : "")}:", Url = e.PublicUrl })
.ToArrayAsync())
.DistinctBy(e => e.Name)
.ToDictionary(e => e.Name, e => e.Url);
//TODO: can we somehow optimize this to do the dedupe database side?
var emojiUrls = await urlQ.Select(e => new
{
Name = $":{e.Name}{(e.Host != null ? "@" + e.Host : "")}:",
Url = e.PublicUrl
})
.ToArrayAsync()
.ContinueWithResult(res => res.DistinctBy(e => e.Name)
.ToDictionary(e => e.Name, e => e.Url));
return await notificationList
.Select(p => RenderAsync(p, user, isPleroma, accounts, notes, emojiUrls))

View file

@ -1,8 +1,8 @@
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Middleware;
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
using static Iceshrimp.Backend.Core.Database.Tables.Notification;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
namespace Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;

View file

@ -45,9 +45,7 @@ public abstract class StatusSchemas
[B(Name = "poll")] [J("poll")] public PollData? Poll { get; set; }
[B(Name = "preview")]
[J("preview")]
public bool Preview { get; set; } = false;
[B(Name = "preview")] [J("preview")] public bool Preview { get; set; } = false;
public class PollData
{

View file

@ -21,11 +21,13 @@ public class EmojiController(DatabaseContext db) : ControllerBase
[ProducesResults(HttpStatusCode.OK)]
public async Task<Dictionary<string, PleromaEmojiEntity>> GetCustomEmojis()
{
var emoji = await db.Emojis.Where(p => p.Host == null)
.Select(p => KeyValuePair.Create(p.Name, new PleromaEmojiEntity
var emoji = await db.Emojis
.Where(p => p.Host == null)
.Select(p => KeyValuePair.Create(p.Name,
new PleromaEmojiEntity
{
ImageUrl = p.PublicUrl,
Tags = new string[] { p.Category == null ? "" : p.Category }
Tags = new[] { p.Category ?? "" }
}))
.ToArrayAsync();

View file

@ -4,10 +4,8 @@ using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas;
using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Shared.Attributes;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Middleware;
using Microsoft.AspNetCore.Cors;
@ -27,17 +25,17 @@ public class NotificationController(DatabaseContext db, NotificationRenderer not
[HttpPost("/api/v1/pleroma/notifications/read")]
[Authorize("read:notifications")]
[ProducesResults(HttpStatusCode.OK)]
public async Task<List<NotificationEntity>> MarkNotificationsAsRead([FromHybrid] PleromaNotificationSchemas.ReadNotificationsRequest request)
public async Task<List<NotificationEntity>> MarkNotificationsAsRead(
[FromHybrid] PleromaNotificationSchemas.ReadNotificationsRequest request
)
{
var user = HttpContext.GetUserOrFail();
if (request.Id != null && request.MaxId != null)
if (request is { Id: not null, MaxId: not null })
throw GracefulException.BadRequest("id and max_id are mutually exclusive.");
var q = db.Notifications
.IncludeCommonProperties()
.Include(p => p.Notifier)
.Include(p => p.Note)
.Where(p => p.Notifiee == user)
.Where(p => p.Notifier != null)
.Where(p => !p.IsRead)

View file

@ -11,7 +11,22 @@ public class PleromaInstanceExtensions
public class InstanceMetadata
{
[J("post_formats")] public string[] PostFormats => ["text/plain", "text/x.misskeymarkdown"];
[J("features")] public string[] Features => ["pleroma_api", "akkoma_api", "mastodon_api", "mastodon_api_streaming", "polls", "quote_posting", "editing", "pleroma_emoji_reactions", "exposable_reactions", "custom_emoji_reactions"];
[J("features")]
public string[] Features =>
[
"pleroma_api",
"akkoma_api",
"mastodon_api",
"mastodon_api_streaming",
"polls",
"quote_posting",
"editing",
"pleroma_emoji_reactions",
"exposable_reactions",
"custom_emoji_reactions"
];
[J("fields_limits")] public FieldsLimits FieldsLimits => new();
}

View file

@ -2,13 +2,12 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
namespace Iceshrimp.Backend.Controllers.Pleroma.Schemas;
public class FrontendConfigurationsResponse()
public class FrontendConfigurationsResponse
{
[J("pleroma_fe")] public PleromaFeConfiguration PleromaFe => new();
}
public class PleromaFeConfiguration()
public class PleromaFeConfiguration
{
[J("loginMethod")] public string LoginMethod => "token";
[J("useStreamingApi")] public bool UseStreamingApi => true;

View file

@ -2,12 +2,10 @@ using System.Net;
using System.Net.Mime;
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Controllers.Shared.Attributes;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Middleware;
using Iceshrimp.Backend.Core.Services;

View file

@ -31,7 +31,6 @@ public class IdenticonController : ControllerBase
var gradient = new LinearGradientBrush(new Point(0, 0), new Point(Size, Size), GradientRepetitionMode.None,
new ColorStop(0, color.start), new ColorStop(1, color.end));
image.Mutate(p => p.Fill(gradient));
var paint = new SolidBrush(Color.White);

View file

@ -12,7 +12,7 @@ public static class FilterRenderer
Expiry = filter.Expiry,
Keywords = filter.Keywords,
Action = (FilterResponse.FilterAction)filter.Action,
Contexts = filter.Contexts.Cast<FilterResponse.FilterContext>().ToList(),
Contexts = filter.Contexts.Cast<FilterResponse.FilterContext>().ToList()
};
public static IEnumerable<FilterResponse> RenderMany(IEnumerable<Filter> filters) => filters.Select(RenderOne);

View file

@ -30,7 +30,7 @@ public class SettingsController(DatabaseContext db) : ControllerBase
AlwaysMarkSensitive = settings.AlwaysMarkSensitive,
AutoAcceptFollowed = settings.AutoAcceptFollowed,
DefaultNoteVisibility = (NoteVisibility)settings.DefaultNoteVisibility,
DefaultRenoteVisibility = (NoteVisibility)settings.DefaultNoteVisibility,
DefaultRenoteVisibility = (NoteVisibility)settings.DefaultNoteVisibility
};
}

View file

@ -537,7 +537,7 @@ public static class QueryableExtensions
)
{
if (request.ExcludeReplies)
query = query.Where(p => p.Reply == null && p.ReplyUri == null || p.ReplyUserId == p.UserId);
query = query.Where(p => (p.Reply == null && p.ReplyUri == null) || p.ReplyUserId == p.UserId);
if (request.ExcludeRenotes)
query = query.Where(p => p.Renote == null && p.RenoteUri == null);
if (request.Tagged != null)

View file

@ -112,8 +112,24 @@ public class NodeInfoResponse
[J("enableEmail")] public bool? EnableEmail { get; set; }
[J("post_formats")] public string[] PostFormats => ["text/plain", "text/x.misskeymarkdown"];
[J("features")] public string[] Features => ["pleroma_api", "akkoma_api", "mastodon_api", "mastodon_api_streaming", "polls", "quote_posting", "editing", "pleroma_emoji_reactions", "exposable_reactions", "custom_emoji_reactions"];
[J("features")]
public string[] Features =>
[
"pleroma_api",
"akkoma_api",
"mastodon_api",
"mastodon_api_streaming",
"polls",
"quote_posting",
"editing",
"pleroma_emoji_reactions",
"exposable_reactions",
"custom_emoji_reactions"
];
[J("localBubbleInstances")] public string[] LocalBubbleInstances { get; set; } = [];
// TODO: list of ap object ids i believe?
[J("staffAccounts")] public string[] StaffAccounts { get; set; } = [];

View file

@ -64,7 +64,7 @@ public static class BlurhashHelper
var dc = factors[0];
var acCount = componentsX * componentsY - 1;
var sizeFlag = (componentsX - 1) + (componentsY - 1) * 9;
var sizeFlag = componentsX - 1 + (componentsY - 1) * 9;
sizeFlag.EncodeBase83(resultBuffer[..1]);
float maximumValue;

View file

@ -1,4 +1,5 @@
using System.IO.Compression;
using System.Net;
using System.Text.Json;
using Iceshrimp.Backend.Core.Middleware;
using Microsoft.AspNetCore.StaticFiles;
@ -39,16 +40,18 @@ public class EmojiImportService(
try
{
var meta = archive.GetEntry("meta.json")
?? throw GracefulException.BadRequest("Invalid emoji zip. Only Misskey-style emoji zips are supported.");
var meta = archive.GetEntry("meta.json") ??
throw GracefulException
.BadRequest("Invalid emoji zip. Only Misskey-style emoji zips are supported.");
var metaJson = await JsonSerializer.DeserializeAsync<EmojiZipMeta>(meta.Open(), SerializerOptions)
?? throw GracefulException.BadRequest("Invalid emoji zip metadata");
var metaJson = await JsonSerializer.DeserializeAsync<EmojiZipMeta>(meta.Open(), SerializerOptions) ??
throw GracefulException.BadRequest("Invalid emoji zip metadata");
if (metaJson.MetaVersion < 1 || metaJson.MetaVersion > 2)
throw GracefulException.BadRequest("Unrecognized metaVersion {version}, expected 1 or 2", metaJson.MetaVersion.ToString());
throw GracefulException.BadRequest("Unrecognized metaVersion {version}, expected 1 or 2",
metaJson.MetaVersion.ToString());
return new(metaJson, archive);
return new EmojiZip(metaJson, archive);
}
catch
{
@ -97,7 +100,7 @@ public class EmojiImportService(
logger.LogDebug("Imported emoji {emoji}", name);
}
catch (GracefulException e) when (e.StatusCode == System.Net.HttpStatusCode.Conflict)
catch (GracefulException e) when (e.StatusCode == HttpStatusCode.Conflict)
{
logger.LogDebug("Skipping {emoji} as it already exists.", name);
}

View file

@ -81,6 +81,7 @@ public class ImageProcessor
_logger.LogWarning("No image processor supports the format {format}, skipping", p.Format.MimeType);
return null;
}
return async () =>
{
if (_concurrency is 0)

View file

@ -11,7 +11,8 @@ using Microsoft.EntityFrameworkCore;
namespace Iceshrimp.Backend.Core.Services;
/// <summary>
/// This is needed because static fields in generic classes aren't shared between instances with different generic type arguments
/// This is needed because static fields in generic classes aren't shared between instances with different generic type
/// arguments
/// </summary>
file static class PluginStoreHelpers
{

View file

@ -91,7 +91,7 @@ public class AuthorizeModel(DatabaseContext db) : PageModel
RedirectUri = RedirectUri,
AutoDetectQuotes = autoDetectQuotes,
SupportsHtmlFormatting = supportsHtmlFormatting,
IsPleroma = isPleroma,
IsPleroma = isPleroma
};
await db.AddAsync(token);

View file

@ -13,7 +13,7 @@ public class QueueJobModel(DatabaseContext db) : PageModel
{
["inbox"] = "body",
["deliver"] = "payload",
["pre-deliver"] = "serializedActivity",
["pre-deliver"] = "serializedActivity"
};
public Job Job = null!;

View file

@ -1,6 +1,6 @@
@using Iceshrimp.Frontend.Components
@using Microsoft.AspNetCore.Components.Authorization
<ErrorBoundary @ref=ErrorBoundary>
<ErrorBoundary @ref="ErrorBoundary">
<ChildContent>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">

View file

@ -1,6 +1,5 @@
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Shared.Schemas.Web
@if (Attachment.ContentType.StartsWith("image"))
{
<div class="wrapper" @onclick="Open" @onclick:stopPropagation="true">

View file

@ -1,7 +1,7 @@
<div @onclick="Close" @onclick:stopPropagation="true" class="backdrop @(Darken ? "darken" : "")"></div>
@code {
[Parameter][EditorRequired] public required EventCallback OnClose { get; set; }
[Parameter] [EditorRequired] public required EventCallback OnClose { get; set; }
[Parameter] public bool Darken { get; set; }
private void Close()

View file

@ -20,7 +20,7 @@
<Icon Name="Icons.X"/>
</button>
<Dropdown TBind="NoteVisibility" Elements="@DropDownCreate()" @bind-Value="NoteDraft.Visibility"/>
<StateButton OnClick="SendNote" @ref=SendButton ExtraClasses="post-btn">
<StateButton OnClick="SendNote" @ref="SendButton" ExtraClasses="post-btn">
<Initial>
@Loc["ComposePost"]<Icon Name="Icons.PaperPlaneRight"/>
</Initial>
@ -84,7 +84,12 @@
Cw = null
};
private Dictionary<string, string> AvailablePlaceholders { get; set; } = new() { { "default", "What's on your mind?" }, { "reply", "Reply goes here!" }, { "quote", "Quote this post!" } };
private Dictionary<string, string> AvailablePlaceholders { get; set; } = new()
{
{ "default", "What's on your mind?" },
{ "reply", "Reply goes here!" },
{ "quote", "Quote this post!" }
};
RenderFragment DropdownIcon(NoteVisibility vis)
{
@ -117,7 +122,9 @@
new DropdownElement<NoteVisibility>
{
#pragma warning disable BL0005 // Setting this outside the component is fine until this is reworked
Icon = DropdownIcon(vis), Content = DropdownContent(vis), Selection = vis
Icon = DropdownIcon(vis),
Content = DropdownContent(vis),
Selection = vis
#pragma warning restore BL0005
})
.ToList();
@ -212,7 +219,12 @@
{
ReplyOrQuote = null;
Attachments = new List<DriveFileResponse>();
NoteDraft = new NoteCreateRequest { Text = "", Visibility = NoteVisibility.Followers, Cw = null };
NoteDraft = new NoteCreateRequest
{
Text = "",
Visibility = NoteVisibility.Followers,
Cw = null
};
TextPlaceholder = AvailablePlaceholders["default"];
}

View file

@ -40,8 +40,7 @@
}
</div>
@Loc["Logs"]
@Loc["These logs may contain sensitive information, please do not post them publicly.\n" +
"Providing them to developers upon request may help with debugging."]
@Loc["These logs may contain sensitive information, please do not post them publicly.\n" + "Providing them to developers upon request may help with debugging."]
<div class="log-block">
<pre><code>
@foreach (var line in _rawLog)
@ -70,14 +69,12 @@
protected override async Task OnInitializedAsync()
{
_rawLog = LogService.GetLogs();
_module = (IJSInProcessObjectReference) await Js.InvokeAsync<IJSObjectReference>("import", "./Components/ErrorUi.razor.js");
_module = (IJSInProcessObjectReference)await Js.InvokeAsync<IJSObjectReference>("import", "./Components/ErrorUi.razor.js");
}
private void DownloadLogs()
{
var logBytes = LogService.GetLogs().SelectMany(p => Encoding.UTF8.GetBytes(p)).ToArray();
_module.InvokeVoid("DownloadFile", "log.txt", "text/plain", logBytes);
}
}

View file

@ -1,8 +1,8 @@
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Services
@inject IStringLocalizer<Localization> Loc;
@inject ApiService Api;
<span class="follow-button">

View file

@ -1,8 +1,8 @@
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Services
@inject IStringLocalizer<Localization> Loc;
@inject ApiService Api;
@inject NavigationManager NavigationManager;

View file

@ -1,4 +1,4 @@
<EmojiPicker></EmojiPicker>
@code {
@code {
}

View file

@ -1,4 +1,3 @@
@if (_display)
{
<div class="menu">

View file

@ -1,5 +1,4 @@
@using Iceshrimp.Assets.PhosphorIcons
<div @onclick="OnClick" class="menu-element">
@if (Icon != null)
{
@ -7,6 +6,7 @@
}
@Text
</div>
@code {
[Parameter] public IconName? Icon { get; set; }
[Parameter] [EditorRequired] public required RenderFragment Text { get; set; }

View file

@ -1,12 +1,12 @@
@using Iceshrimp.Assets.PhosphorIcons
<CascadingValue Value="this">
@if (NoteResponse.Renote != null)
{
@if (NoteResponse.Renote != null)
{
<div class="renote">
<div class="renote-info">
<span class="user">
<Icon Name="Icons.Repeat" /> Boosted by
<Icon Name="Icons.Repeat"/> Boosted by
@if (NoteResponse.User.DisplayName != null)
{
@NoteResponse.User.DisplayName
@ -22,9 +22,9 @@
</div>
<NoteComponent Note="NoteResponse.Renote" Quote="NoteResponse.Quote" Indented="Indented"/>
</div>
}
else
{
}
else
{
@if (NoteResponse.Filtered is not null && NoteResponse.Filtered.Hide == false)
{
<div>
@ -43,11 +43,12 @@ else
</button>
</div>
}
@if (_overrideHide || NoteResponse.Filtered == null)
{
<NoteComponent Note="NoteResponse" Quote="NoteResponse.Quote" Indented="Indented"/>
}
}
}
</CascadingValue>

View file

@ -4,7 +4,7 @@
@inject NavigationManager NavigationManager
@inject ComposeService ComposeService
@inject SessionService Session;
<div class="note-header">
<div class="note-header">
<NoteUserInfo
AvatarUrl="@Note.User.AvatarUrl"
DisplayName="@Note.User.DisplayName"
@ -16,16 +16,16 @@
InstanceName="@Note.User.InstanceName"
CreatedAt="DateTime.Parse(Note.CreatedAt)">
</NoteMetadata>
</div>
<NoteBody NoteBase="Note" OverLength="@CheckLen()" Indented="Indented"/>
@if (Quote != null)
{
</div>
<NoteBody NoteBase="Note" OverLength="@CheckLen()" Indented="Indented"/>
@if (Quote != null)
{
<div @onclick="OpenQuote" @onclick:stopPropagation="true" class="quote">
<NoteComponent Note="Quote" AsQuote="true"></NoteComponent>
</div>
}
@if (!AsQuote)
{
}
@if (!AsQuote)
{
<NoteFooter
Reactions="Note.Reactions"
Likes="Note.Likes"
@ -33,7 +33,7 @@
Renotes="Note.Renotes"
RenotePossible=
"@(Note.Visibility == NoteVisibility.Public || Note.Visibility == NoteVisibility.Home || Session.Current?.Id == Note.User.Id)"/>
}
}
@code {
[Parameter] [EditorRequired] public required NoteBase Note { get; set; }

View file

@ -21,7 +21,7 @@
<button class="btn" @onclick="Reply" @onclick:stopPropagation="true">
<Icon Name="Icons.ArrowUUpLeft" Size="1.3em"/>
</button>
<button class="btn @(RenotePossible ? "" : "disabled") positioned" @onclick="@(RenotePossible ? ToggleRenoteMenu : () => {})" @onclick:stopPropagation="true">
<button class="btn @(RenotePossible ? "" : "disabled") positioned" @onclick="@(RenotePossible ? ToggleRenoteMenu : () => { })" @onclick:stopPropagation="true">
@if (RenotePossible)
{
<Icon Name="Icons.Repeat" Size="1.3em"/>

View file

@ -7,7 +7,7 @@
@inject NavigationManager NavigationManager
<div class="notification">
@if (NotificationResponse is { User: not null, Type: "like" or "follow" or "reaction" or "followRequestReceived" or "followRequestAccepted"})
@if (NotificationResponse is { User: not null, Type: "like" or "follow" or "reaction" or "followRequestReceived" or "followRequestAccepted" })
{
<img class="user-avatar" src="@NotificationResponse.User.AvatarUrl"/>
<div class="notification-body">

View file

@ -101,7 +101,6 @@
Note.Descendants = res;
StateHasChanged();
}
}
private void OpenNote()

View file

@ -1,11 +1,11 @@
@using System.Diagnostics.CodeAnalysis
@* ReSharper disable once RedundantUsingDirective *@
@using Iceshrimp.Frontend.Components.Note
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Microsoft.Extensions.Localization
@* ReSharper disable once RedundantUsingDirective *@
@using Iceshrimp.Frontend.Components.Note
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<Localization> Loc;
@inject ApiService Api;
@inject NavigationManager Navigation;

View file

@ -25,5 +25,4 @@
</div>
@code {
}

View file

@ -10,11 +10,11 @@
</button>
@code {
[Parameter, EditorRequired] public required EventCallback OnClick { get; set; }
[Parameter, EditorRequired] public required RenderFragment Initial { get; set; }
[Parameter, EditorRequired] public required RenderFragment Loading { get; set; }
[Parameter, EditorRequired] public required RenderFragment Failed { get; set; }
[Parameter, EditorRequired] public required RenderFragment Success { get; set; }
[Parameter] [EditorRequired] public required EventCallback OnClick { get; set; }
[Parameter] [EditorRequired] public required RenderFragment Initial { get; set; }
[Parameter] [EditorRequired] public required RenderFragment Loading { get; set; }
[Parameter] [EditorRequired] public required RenderFragment Failed { get; set; }
[Parameter] [EditorRequired] public required RenderFragment Success { get; set; }
[Parameter] public string? ExtraClasses { get; set; }
public StateEnum State { get; set; }

View file

@ -34,6 +34,7 @@ public partial class TimelineComponent : IAsyncDisposable
{
return false;
}
State.MaxId = res[0].Id;
State.MinId = res.Last().Id;
State.Timeline = res;
@ -124,6 +125,7 @@ public partial class TimelineComponent : IAsyncDisposable
{
initResult = await Initialize();
}
ComponentState = initResult ? Core.Miscellaneous.State.Loaded : Core.Miscellaneous.State.Empty;
StateHasChanged();
}

View file

@ -2,15 +2,12 @@
@using Iceshrimp.Frontend.Components.Note
@using Iceshrimp.Shared.Schemas.Web
@inject NavigationManager Navigation
@if (Note.Filtered is { Hide: true })
@if (Note.Filtered is { Hide: true }) { }
else
{
}
else {
<div class="note-container" @onclick="OpenNote" id="@Note.Id">
<Note NoteResponse="Note"></Note>
</div>
}
@code {

View file

@ -1,6 +1,6 @@
@inject ApiService Api;
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Shared.Schemas.Web
@inject ApiService Api;
@inject NavigationManager NavigationManager;
@if (UserProfile != null)
{

View file

@ -1,4 +1,3 @@
<div @ref="@_scroller" class="scroller">
<div @ref="@_padTopRef" class="padding top" style="height: @(State.PadTop + "px")"></div>
@if (_loadingTop)
@ -30,5 +29,4 @@
</div>
@code {
}

View file

@ -277,7 +277,9 @@ public partial class VirtualScroller : IAsyncDisposable
{
if (firstRender)
{
Module = (IJSInProcessObjectReference) await Js.InvokeAsync<IJSObjectReference>("import", "./Components/VirtualScroller.razor.js");
Module =
(IJSInProcessObjectReference)
await Js.InvokeAsync<IJSObjectReference>("import", "./Components/VirtualScroller.razor.js");
await SetupObservers();
}

View file

@ -6,6 +6,7 @@ namespace Iceshrimp.Frontend.Core.InMemoryLogger;
internal class InMemoryLogService(IOptions<InMemoryLoggerConfiguration> configuration)
{
private readonly LogBuffer _buffer = new(configuration.Value.BufferSize);
public void Add(string logline)
{
_buffer.Add(logline);

View file

@ -2,9 +2,12 @@ using Microsoft.Extensions.Options;
namespace Iceshrimp.Frontend.Core.InMemoryLogger;
internal class InMemoryLogger (IOptions<InMemoryLoggerConfiguration> config, InMemoryLogService logService) : ILogger
internal class InMemoryLogger(IOptions<InMemoryLoggerConfiguration> config, InMemoryLogService logService) : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
public void Log<TState>(
LogLevel logLevel, EventId eventId, TState state, Exception? exception,
Func<TState, Exception?, string> formatter
)
{
logService.Add(formatter(state, exception));
}

View file

@ -1,19 +1,19 @@
namespace Iceshrimp.Frontend.Core.InMemoryLogger;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
namespace Iceshrimp.Frontend.Core.InMemoryLogger;
internal static class InMemoryLoggerExtension
{
public static void AddInMemoryLogger(
this ILoggingBuilder builder, IConfiguration configuration)
this ILoggingBuilder builder, IConfiguration configuration
)
{
builder.AddConfiguration();
builder.Services.AddOptionsWithValidateOnStart<InMemoryLoggerConfiguration>()
.Bind(configuration.GetSection("InMemoryLogger"));
LoggerProviderOptions.RegisterProviderOptions<InMemoryLoggerConfiguration, InMemoryLoggerProvider>(builder.Services);
LoggerProviderOptions
.RegisterProviderOptions<InMemoryLoggerConfiguration, InMemoryLoggerProvider>(builder.Services);
builder.Services.TryAddSingleton<InMemoryLogService>();
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, InMemoryLoggerProvider>());
}
@ -28,5 +28,3 @@ internal static class InMemoryLoggerExtension
builder.Services.Configure(configure);
}
}

View file

@ -93,7 +93,7 @@ public readonly struct QueryString : IEquatable<QueryString>
{
ArgumentNullException.ThrowIfNull(uri);
string queryValue = uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped);
var queryValue = uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped);
if (!string.IsNullOrEmpty(queryValue))
{
queryValue = "?" + queryValue;
@ -170,10 +170,10 @@ public readonly struct QueryString : IEquatable<QueryString>
}
/// <summary>
/// Concatenates <paramref name="other"/> to the current query string.
/// Concatenates <paramref name="other" /> to the current query string.
/// </summary>
/// <param name="other">The <see cref="QueryString"/> to concatenate.</param>
/// <returns>The concatenated <see cref="QueryString"/>.</returns>
/// <param name="other">The <see cref="QueryString" /> to concatenate.</param>
/// <returns>The concatenated <see cref="QueryString" />.</returns>
public QueryString Add(QueryString other)
{
if (!HasValue || Value.Equals("?", StringComparison.Ordinal))
@ -191,12 +191,12 @@ public readonly struct QueryString : IEquatable<QueryString>
}
/// <summary>
/// Concatenates a query string with <paramref name="name"/> and <paramref name="value"/>
/// Concatenates a query string with <paramref name="name" /> and <paramref name="value" />
/// to the current query string.
/// </summary>
/// <param name="name">The name of the query string to concatenate.</param>
/// <param name="value">The value of the query string to concatenate.</param>
/// <returns>The concatenated <see cref="QueryString"/>.</returns>
/// <returns>The concatenated <see cref="QueryString" />.</returns>
public QueryString Add(string name, string value)
{
ArgumentNullException.ThrowIfNull(name);
@ -212,10 +212,10 @@ public readonly struct QueryString : IEquatable<QueryString>
}
/// <summary>
/// Evalutes if the current query string is equal to <paramref name="other"/>.
/// Evalutes if the current query string is equal to <paramref name="other" />.
/// </summary>
/// <param name="other">The <see cref="QueryString"/> to compare.</param>
/// <returns><see langword="true"/> if the query strings are equal.</returns>
/// <param name="other">The <see cref="QueryString" /> to compare.</param>
/// <returns><see langword="true" /> if the query strings are equal.</returns>
public bool Equals(QueryString other)
{
if (!HasValue && !other.HasValue)
@ -227,7 +227,7 @@ public readonly struct QueryString : IEquatable<QueryString>
}
/// <summary>
/// Evaluates if the current query string is equal to an object <paramref name="obj"/>.
/// Evaluates if the current query string is equal to an object <paramref name="obj" />.
/// </summary>
/// <param name="obj">An object to compare.</param>
/// <returns><see langword="true" /> if the query strings are equal.</returns>
@ -244,17 +244,17 @@ public readonly struct QueryString : IEquatable<QueryString>
/// <summary>
/// Gets a hash code for the value.
/// </summary>
/// <returns>The hash code as an <see cref="int"/>.</returns>
/// <returns>The hash code as an <see cref="int" />.</returns>
public override int GetHashCode()
{
return (HasValue ? Value.GetHashCode() : 0);
return HasValue ? Value.GetHashCode() : 0;
}
/// <summary>
/// Evaluates if one query string is equal to another.
/// </summary>
/// <param name="left">A <see cref="QueryString"/> instance.</param>
/// <param name="right">A <see cref="QueryString"/> instance.</param>
/// <param name="left">A <see cref="QueryString" /> instance.</param>
/// <param name="right">A <see cref="QueryString" /> instance.</param>
/// <returns><see langword="true" /> if the query strings are equal.</returns>
public static bool operator ==(QueryString left, QueryString right)
{
@ -264,8 +264,8 @@ public readonly struct QueryString : IEquatable<QueryString>
/// <summary>
/// Evaluates if one query string is not equal to another.
/// </summary>
/// <param name="left">A <see cref="QueryString"/> instance.</param>
/// <param name="right">A <see cref="QueryString"/> instance.</param>
/// <param name="left">A <see cref="QueryString" /> instance.</param>
/// <param name="right">A <see cref="QueryString" /> instance.</param>
/// <returns><see langword="true" /> if the query strings are not equal.</returns>
public static bool operator !=(QueryString left, QueryString right)
{
@ -273,11 +273,11 @@ public readonly struct QueryString : IEquatable<QueryString>
}
/// <summary>
/// Concatenates <paramref name="left"/> and <paramref name="right"/> into a single query string.
/// Concatenates <paramref name="left" /> and <paramref name="right" /> into a single query string.
/// </summary>
/// <param name="left">A <see cref="QueryString"/> instance.</param>
/// <param name="right">A <see cref="QueryString"/> instance.</param>
/// <returns>The concatenated <see cref="QueryString"/>.</returns>
/// <param name="left">A <see cref="QueryString" /> instance.</param>
/// <param name="right">A <see cref="QueryString" /> instance.</param>
/// <returns>The concatenated <see cref="QueryString" />.</returns>
public static QueryString operator +(QueryString left, QueryString right)
{
return left.Add(right);

View file

@ -24,6 +24,4 @@ internal class EmojiService(ApiService api)
throw new Exception("Failed to fetch emoji");
}
}
}

View file

@ -1,4 +1,5 @@
using Iceshrimp.Frontend.Components;
namespace Iceshrimp.Frontend.Core.Services;
public class GlobalComponentSvc

View file

@ -9,12 +9,12 @@ internal class MessageService
private readonly Dictionary<(string, Type), EventHandler<NoteResponse>> _noteChangedHandlers = new();
public enum Type
{
Updated,
Deleted
}
public NoteMessageHandler Register(string id, EventHandler<NoteResponse> func, Type type)
{
var tuple = (id, type);
@ -52,7 +52,9 @@ internal class MessageService
private readonly Type _type;
private readonly MessageService _messageService;
public NoteMessageHandler(EventHandler<NoteResponse> handler, string id, Type type, MessageService messageService)
public NoteMessageHandler(
EventHandler<NoteResponse> handler, string id, Type type, MessageService messageService
)
{
_handler = handler;
_id = id;

View file

@ -14,7 +14,6 @@ public class SingleNote
States.TryGetValue(id, out var state);
return state;
}
}
public class SingleNoteState

View file

@ -60,6 +60,7 @@ internal class TimelineState : IDisposable
Timeline.RemoveAt(i);
return;
}
if (i == 0) MaxId = Timeline[1].Id;
if (i == Timeline.Count - 1) MinId = Timeline[^2].Id;
Timeline.RemoveAt(i);

View file

@ -1,6 +1,5 @@
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.AspNetCore.Components.Authorization
@inherits LayoutComponentBase
<div class="page">

View file

@ -1,8 +1,7 @@
@using Iceshrimp.Frontend.Components
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@inherits LayoutComponentBase
@layout MainLayout

View file

@ -1,13 +1,13 @@
@inject IStringLocalizer<Localization> Loc;
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<Localization> Loc;
@implements IDisposable
@inject NavigationManager Navigation;
<GlobalComponents></GlobalComponents>
<div @ref="SidebarElementRef" class="sidebar @(_open ? "open" : "")" tabindex=0>
<div @ref="SidebarElementRef" class="sidebar @(_open ? "open" : "")" tabindex="0">
<div class="header">
<account-dropdown/>
</div>
@ -49,7 +49,7 @@
</button>
@if (_open)
{
<ClosingBackdrop OnClose="Close" />
<ClosingBackdrop OnClose="Close"/>
}
</div>

View file

@ -1,11 +1,11 @@
@page "/follow-requests"
@attribute [Authorize]
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.Extensions.Localization
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@inject IStringLocalizer<Localization> Loc;
<SectionContent SectionName="top-bar">
@ -13,7 +13,7 @@
@Loc["Follow requests"]
</SectionContent>
<FollowRequestList />
@code {
<FollowRequestList/>
@code {
}

View file

@ -1,11 +1,11 @@
@page "/notifications"
@attribute [Authorize]
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.Extensions.Localization
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@inject IStringLocalizer<Localization> Loc;

View file

@ -1,6 +1,4 @@
@page "/{User}"
@attribute [Authorize]
@using System.Text.RegularExpressions
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Components.Note
@ -8,6 +6,7 @@
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject ApiService Api
@if (_init)

View file

@ -1,11 +1,11 @@
@page "/search"
@attribute [Authorize]
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.Extensions.Localization
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@inject IStringLocalizer<Localization> Loc;
@ -14,7 +14,7 @@
@Loc["Search"]
</SectionContent>
<SearchComponent />
@code {
<SearchComponent/>
@code {
}

View file

@ -1,11 +1,11 @@
@page "/settings/about"
@attribute [Authorize]
@using System.Text
@using Iceshrimp.Frontend.Core.InMemoryLogger
@using Iceshrimp.Frontend.Core.Services;
@using Iceshrimp.Frontend.Localization;
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Extensions.Localization;
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@layout SettingsLayout;
@inject VersionService Version;
@inject IStringLocalizer<Localization> Loc;
@ -36,8 +36,7 @@
</div>
<div class="logs">
<h1>@Loc["Logs"]</h1>
@Loc["These logs may contain sensitive information, please do not post them publicly.\n"
+ "Providing them to developers upon request may help with debugging."]
@Loc["These logs may contain sensitive information, please do not post them publicly.\n" + "Providing them to developers upon request may help with debugging."]
<button class="btn" @onclick="DownloadLogs">@Loc["Download Logs"]</button>
</div>
@ -46,7 +45,7 @@
protected override async Task OnInitializedAsync()
{
_module = (IJSInProcessObjectReference) await Js.InvokeAsync<IJSObjectReference>("import", "./Components/ErrorUi.razor.js");
_module = (IJSInProcessObjectReference)await Js.InvokeAsync<IJSObjectReference>("import", "./Components/ErrorUi.razor.js");
}
private void DownloadLogs()
@ -54,5 +53,4 @@
var logBytes = LogService.GetLogs().SelectMany(p => Encoding.UTF8.GetBytes(p)).ToArray();
_module.InvokeVoid("DownloadFile", "log.txt", "text/plain", logBytes);
}
}

View file

@ -1,14 +1,14 @@
@page "/settings/filters"
@attribute [Authorize]
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@layout SettingsLayout
@inject ApiService Api;
@inject IStringLocalizer<Localization> Loc;
@ -177,7 +177,7 @@
private State State { get; set; } = State.Loading;
private string FilterName { get; set; } = "";
private string Keyword { get; set; } = "";
private List<String> FilterKeywords { get; } = [];
private List<string> FilterKeywords { get; } = [];
private DateTime? FilterExpiry { get; set; }
private FilterResponse.FilterAction FilterAction { get; set; }
private Menu MenuFilterAction { get; set; } = null!;
@ -217,7 +217,7 @@
private async Task TryAddFilter()
{
bool valid = true;
var valid = true;
if (FilterName.Length < 1)
{

View file

@ -1,14 +1,13 @@
@page "/settings/profile"
@attribute [Authorize]
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Extensions.Logging
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@layout SettingsLayout
@inject ApiService Api;
@inject ILogger<Profile> Logger;
@ -50,10 +49,18 @@
<div class="section">
<StateButton OnClick="SaveChanges" @ref="SaveButton">
<Initial><Icon Name="Icons.FloppyDisk"/>@Loc["Save"]</Initial>
<Loading><Icon Name="Icons.Spinner"/></Loading>
<Failed><Icon Name="Icons.X" />@Loc["Error"]</Failed>
<Success><Icon Name="Icons.Check"/>@Loc["Saved"]</Success>
<Initial>
<Icon Name="Icons.FloppyDisk"/>@Loc["Save"]
</Initial>
<Loading>
<Icon Name="Icons.Spinner"/>
</Loading>
<Failed>
<Icon Name="Icons.X"/>@Loc["Error"]
</Failed>
<Success>
<Icon Name="Icons.Check"/>@Loc["Saved"]
</Success>
</StateButton>
</div>
}

View file

@ -1,11 +1,11 @@
@page "/Settings"
@attribute [Authorize]
@using Iceshrimp.Frontend.Components
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@* @inject NavigationManager Nav; *@
@inject IStringLocalizer<Localization> Loc;

View file

@ -1,16 +1,5 @@
@page "/notes/{NoteId}"
@attribute [Authorize]
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Components.Note
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Core.Services.StateServicePatterns
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Microsoft.AspNetCore.Authorization
@inject ApiService ApiService
@inject IJSRuntime Js
@inject MessageService MessageService
@ -19,6 +8,17 @@
@inject IStringLocalizer<Localization> Loc
@inject ILogger<SingleNote> Logger;
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Components.Note
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Core.Services.StateServicePatterns
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@implements IDisposable
@if (_componentState == LoadState.Init)
@ -114,11 +114,13 @@
_componentState = LoadState.Error;
return;
}
if (RootNote == null)
{
_componentState = LoadState.Error;
return;
}
_componentState = LoadState.Init;
StateHasChanged();

View file

@ -1,11 +1,11 @@
@page "/"
@attribute [Authorize]
@using Iceshrimp.Frontend.Components
@using Microsoft.AspNetCore.Components.Sections
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Components
@using Iceshrimp.Frontend.Localization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Sections
@using Microsoft.Extensions.Localization
@attribute [Authorize]
@inject IStringLocalizer<Localization> Loc;
<SectionContent SectionName="top-bar">

View file

@ -4,9 +4,7 @@ open System
open FParsec
module SearchQueryFilters =
type Filter() =
class
end
type Filter() = class end
type WordFilter(neg: bool, value: string) =
inherit Filter()

View file

@ -268,7 +268,7 @@ public class MfmTests
List<MfmNode> expected =
[
new MfmTextNode("this is plain text > this is not a quote >this is also not a quote\n"),
new MfmQuoteNode(ListModule.OfSeq<MfmInlineNode>([new MfmTextNode("this is a quote\nthis is part of the same quote\nthis too"),]), false, false),
new MfmQuoteNode(ListModule.OfSeq<MfmInlineNode>([new MfmTextNode("this is a quote\nthis is part of the same quote\nthis too")]), false, false),
new MfmTextNode("this is some plain text inbetween\n"),
new MfmQuoteNode(ListModule.OfSeq<MfmInlineNode>([new MfmTextNode("this is a second quote\nthis is part of the second quote")]), true, false),
new MfmQuoteNode(ListModule.OfSeq<MfmInlineNode>([new MfmTextNode("this is a third quote")]), false, false),