summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Pages/Component/NsfwSwitch.razor4
-rw-r--r--Pages/Component/TagSelectDialog.razor10
-rw-r--r--Pages/Gallery.razor10
-rw-r--r--Pages/TagDefinitions.razor10
-rw-r--r--Program.cs3
-rw-r--r--Services/UserService.cs86
6 files changed, 71 insertions, 52 deletions
diff --git a/Pages/Component/NsfwSwitch.razor b/Pages/Component/NsfwSwitch.razor
index d0f499d..b96606d 100644
--- a/Pages/Component/NsfwSwitch.razor
+++ b/Pages/Component/NsfwSwitch.razor
@@ -1,8 +1,8 @@
@inject IUserService userService
-<Switch InitialValue=userService.ShowNsfw OnToggle=ToggleNsfw/>
+<Switch InitialValue=userService.UserSessionState.ShowNsfw OnToggle=ToggleNsfw/>
@code {
private void ToggleNsfw(bool showNsfw) =>
- userService.ShowNsfw = showNsfw;
+ userService.UserSessionState.ShowNsfw = showNsfw;
} \ No newline at end of file
diff --git a/Pages/Component/TagSelectDialog.razor b/Pages/Component/TagSelectDialog.razor
index 7be5c43..20be31e 100644
--- a/Pages/Component/TagSelectDialog.razor
+++ b/Pages/Component/TagSelectDialog.razor
@@ -71,7 +71,7 @@
public void Hide() => Visible = false;
protected override void OnInitialized() {
- userService.ShowNsfwChanged += ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange += ShowNsfwChanged;
LoadTags();
}
@@ -81,7 +81,7 @@
var selected = SelectedTags.Select(td => td.Guid);
int[] nsfwTags = Array.Empty<int>();
- if(!userService.ShowNsfw)
+ if(!userService.UserSessionState.ShowNsfw)
nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag)
.Select(td => td.ObjectId)
.ToArray();
@@ -91,7 +91,7 @@
.Where(td => td.Source == TagSource.UserTag)
.OrderBy(td => td.Name)
.AsEnumerable()
- .Where(td => userService.ShowNsfw || !td.ImplicitTags
+ .Where(td => userService.UserSessionState.ShowNsfw || !td.ImplicitTags
.IntersectBy(nsfwTags, td => td.ObjectId)
.Any())
.Select(td => new Tuple<TagDefinition, bool>(
@@ -170,7 +170,7 @@
StateHasChanged();
}
- public async void ShowNsfwChanged(object? sender, bool showNsfw) =>
+ public async void ShowNsfwChanged(UserSessionState userSessionState) =>
await InvokeAsync(() => {
LoadTags();
StateHasChanged();
@@ -178,6 +178,6 @@
public void Dispose() {
db.Dispose();
- userService.ShowNsfwChanged -= ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange -= ShowNsfwChanged;
}
}
diff --git a/Pages/Gallery.razor b/Pages/Gallery.razor
index d473c28..762ef7f 100644
--- a/Pages/Gallery.razor
+++ b/Pages/Gallery.razor
@@ -10,7 +10,7 @@
<PageTitle>@Title</PageTitle>
-@if(Ingest && !userService.ShowNsfw) {
+@if(Ingest && !userService.UserSessionState.ShowNsfw) {
<div id="ingest-warning">
<p><center>Ingest feed is not available unless NSFW mode is enabled!</center></p>
<p><center><i>You must enable NSFW mode to continue...</i></center></p>
@@ -68,7 +68,7 @@
private IEnumerator<Media> mediaEnumerator;
protected override void OnInitialized() =>
- userService.ShowNsfwChanged += ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange += ShowNsfwChanged;
protected override void OnParametersSet() => LoadMedia();
@@ -124,7 +124,7 @@
break;
Media? m = enumerator.Current;
- if(!userService.ShowNsfw)
+ if(!userService.UserSessionState.ShowNsfw)
if(m.Tags.Select(t => t.TagDefinitionId).Intersect(nsfwTags).Any() || m.IsIngest)
continue;
@@ -135,7 +135,7 @@
}
}
- private async void ShowNsfwChanged(object? sender, bool showNsfw) {
+ private async void ShowNsfwChanged(UserSessionState userSessionState) {
await InvokeAsync(() => {
LoadMedia();
StateHasChanged();
@@ -144,6 +144,6 @@
public void Dispose() {
mediaEnumerator.Dispose();
- userService.ShowNsfwChanged -= ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange -= ShowNsfwChanged;
}
}
diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor
index f728631..3840c6d 100644
--- a/Pages/TagDefinitions.razor
+++ b/Pages/TagDefinitions.razor
@@ -94,14 +94,14 @@
private string?[] tagNamespaces;
protected override void OnInitialized() =>
- userService.ShowNsfwChanged += ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange += ShowNsfwChanged;
protected override void OnParametersSet() =>
LoadTags();
private void LoadTags() {
int[] nsfwTags = Array.Empty<int>();
- if(!userService.ShowNsfw)
+ if(!userService.UserSessionState.ShowNsfw)
nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag)
.Select(td => td.ObjectId)
.ToArray();
@@ -112,7 +112,7 @@
.OrderBy(td => td.Namespace)
.ThenBy(td => td.Name)
.AsEnumerable()
- .Where(td => userService.ShowNsfw || !td.ImplicitTags
+ .Where(td => userService.UserSessionState.ShowNsfw || !td.ImplicitTags
.IntersectBy(nsfwTags, td => td.ObjectId)
.Any())
.ToArray();
@@ -176,12 +176,12 @@
StateHasChanged();
}
- private async void ShowNsfwChanged(object? sender, bool showNsfw) =>
+ private async void ShowNsfwChanged(UserSessionState userSessionState) =>
await InvokeAsync(() => {
LoadTags();
StateHasChanged();
});
public void Dispose() =>
- userService.ShowNsfwChanged -= ShowNsfwChanged;
+ userService.UserSessionState.OnStateChange -= ShowNsfwChanged;
}
diff --git a/Program.cs b/Program.cs
index e78f0d4..79fe8fa 100644
--- a/Program.cs
+++ b/Program.cs
@@ -8,6 +8,7 @@ namespace HyperBooru;
public class Program {
public static void Main(string[] args) {
var builder = WebApplication.CreateBuilder(args);
+ builder.Services.AddSession();
builder.Services.AddHttpContextAccessor();
builder.Services.AddAuthentication(
CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
@@ -24,6 +25,7 @@ public class Program {
builder.Services.AddScoped<ISearchService, SearchService>();
builder.Services.AddScoped<ITagService, TagService>();
builder.Services.AddScoped<IMediaService, MediaService>();
+ builder.Services.AddSingleton<IGlobalUserService, GlobalUserService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddHostedService<OcrService>();
@@ -34,6 +36,7 @@ public class Program {
using var db = scope.ServiceProvider.GetRequiredService<HBContext>();
db.Database.Migrate();
+ app.UseSession();
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
diff --git a/Services/UserService.cs b/Services/UserService.cs
index 1a2bd8f..39b1963 100644
--- a/Services/UserService.cs
+++ b/Services/UserService.cs
@@ -4,50 +4,30 @@ using Microsoft.EntityFrameworkCore;
namespace HyperBooru.Services;
public interface IUserService {
- public bool ShowNsfw { get; set; }
-
- public event EventHandler<bool> ShowNsfwChanged;
-
- public User User { get; }
+ public UserSessionState UserSessionState { get; }
}
public class UserService : IUserService {
- public bool ShowNsfw {
- get => showNsfw;
- set {
- showNsfw = value;
- ShowNsfwChanged?.Invoke(this, value);
- }
- }
+ public UserSessionState UserSessionState =>
+ globalUserService.GetSessionState(httpContext.Session.Id);
- public User User {
- get {
- if(user is not null)
- return user;
- using var db = dbFactory.CreateDbContext();
- int id = int.Parse(httpContextAccessor
- .HttpContext!.User.Claims
- .First(c => c.Type == "ObjectId")
- .Value);
- return user = db.Users.Find(id)!;
- }
- }
-
- public event EventHandler<bool> ShowNsfwChanged;
-
- private bool showNsfw = false;
-
- private User? user;
-
- private IDbContextFactory<HBContext> dbFactory;
private IHttpContextAccessor httpContextAccessor;
+ private IGlobalUserService globalUserService;
+
+ private HttpContext httpContext =>
+ httpContextAccessor.HttpContext!;
public UserService(
- IDbContextFactory<HBContext> dbFactory,
- IHttpContextAccessor httpContextAccessor) {
+ IHttpContextAccessor httpContextAccessor,
+ IGlobalUserService globalUserService) {
- this.dbFactory = dbFactory;
this.httpContextAccessor = httpContextAccessor;
+ this.globalUserService = globalUserService;
+
+ // HTTP context session states are discarded if no values
+ // are set. Set a dummy value so that the session state
+ // will not be discarded later when we actually need it.
+ httpContext.Session.SetInt32("Persist", 1);
}
public static string HashPassword(string password) =>
@@ -59,3 +39,39 @@ public class UserService : IUserService {
100_000,
512 / 8));
}
+
+public interface IGlobalUserService {
+ public UserSessionState GetSessionState(string id);
+}
+
+public class GlobalUserService : IGlobalUserService {
+ // TODO: prune this list periodically
+ private Dictionary<string, UserSessionState> sessionStates = new();
+
+ public UserSessionState GetSessionState(string id) {
+ sessionStates.TryGetValue(id, out var state);
+
+ if(state is null) {
+ state = new();
+ sessionStates[id] = state;
+ }
+
+ return state;
+ }
+}
+
+public record UserSessionState {
+ public event UserSessionStateChange OnStateChange;
+
+ public bool ShowNsfw {
+ get => showNsfw;
+ set {
+ showNsfw = value;
+ OnStateChange.Invoke(this);
+ }
+ }
+
+ private bool showNsfw = false;
+}
+
+public delegate void UserSessionStateChange(UserSessionState sessionState);