Ensure default reading profile is created when creating a user

This commit is contained in:
Amelia 2025-05-29 23:25:35 +02:00
parent cfc65d14a0
commit cfab91a29b
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
4 changed files with 25 additions and 3 deletions

View file

@ -153,6 +153,9 @@ public class AccountController : BaseApiController
// Assign default streams // Assign default streams
AddDefaultStreamsToUser(user); AddDefaultStreamsToUser(user);
// Assign default reading profile
AddDefaultReadingProfileToUser(user);
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user); var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
if (string.IsNullOrEmpty(token)) return BadRequest(await _localizationService.Get("en", "confirm-token-gen")); if (string.IsNullOrEmpty(token)) return BadRequest(await _localizationService.Get("en", "confirm-token-gen"));
if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Get("en", "validate-email", token)); if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Get("en", "validate-email", token));
@ -669,6 +672,9 @@ public class AccountController : BaseApiController
// Assign default streams // Assign default streams
AddDefaultStreamsToUser(user); AddDefaultStreamsToUser(user);
// Assign default reading profile
AddDefaultReadingProfileToUser(user);
// Assign Roles // Assign Roles
var roles = dto.Roles; var roles = dto.Roles;
var hasAdminRole = dto.Roles.Contains(PolicyConstants.AdminRole); var hasAdminRole = dto.Roles.Contains(PolicyConstants.AdminRole);
@ -779,6 +785,15 @@ public class AccountController : BaseApiController
} }
} }
private void AddDefaultReadingProfileToUser(AppUser user)
{
var profile = new AppUserReadingProfileBuilder(user.Id)
.WithName("Default Profile")
.Build();
user.UserPreferences.ReadingProfiles.Add(profile);
user.UserPreferences.DefaultReadingProfile = profile;
}
/// <summary> /// <summary>
/// Last step in authentication flow, confirms the email token for email /// Last step in authentication flow, confirms the email token for email
/// </summary> /// </summary>

View file

@ -12,6 +12,7 @@ public class AppUserPreferences
#region ReadingProfiles #region ReadingProfiles
public int DefaultReadingProfileId { get; set; } public int DefaultReadingProfileId { get; set; }
public AppUserReadingProfile DefaultReadingProfile { get; set; }
public ICollection<AppUserReadingProfile> ReadingProfiles { get; set; } = null!; public ICollection<AppUserReadingProfile> ReadingProfiles { get; set; } = null!;

View file

@ -21,7 +21,8 @@ public class AppUserBuilder : IEntityBuilder<AppUser>
ApiKey = HashUtil.ApiKey(), ApiKey = HashUtil.ApiKey(),
UserPreferences = new AppUserPreferences UserPreferences = new AppUserPreferences
{ {
Theme = theme ?? Seed.DefaultThemes.First() Theme = theme ?? Seed.DefaultThemes.First(),
ReadingProfiles = [],
}, },
ReadingLists = new List<ReadingList>(), ReadingLists = new List<ReadingList>(),
Bookmarks = new List<AppUserBookmark>(), Bookmarks = new List<AppUserBookmark>(),
@ -31,7 +32,7 @@ public class AppUserBuilder : IEntityBuilder<AppUser>
Devices = new List<Device>(), Devices = new List<Device>(),
Id = 0, Id = 0,
DashboardStreams = new List<AppUserDashboardStream>(), DashboardStreams = new List<AppUserDashboardStream>(),
SideNavStreams = new List<AppUserSideNavStream>() SideNavStreams = new List<AppUserSideNavStream>(),
}; };
} }

View file

@ -45,6 +45,7 @@ import {filter} from "rxjs";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {LoadingComponent} from "../../shared/loading/loading.component"; import {LoadingComponent} from "../../shared/loading/loading.component";
import {ReadingProfileLibrarySelectionComponent} from "./_components/library-selection/reading-profile-library-selection.component"; import {ReadingProfileLibrarySelectionComponent} from "./_components/library-selection/reading-profile-library-selection.component";
import {ToastrService} from "ngx-toastr";
enum TabId { enum TabId {
ImageReader = "image-reader", ImageReader = "image-reader",
@ -114,6 +115,7 @@ export class ManageReadingProfilesComponent implements OnInit {
private accountService: AccountService, private accountService: AccountService,
private bookService: BookService, private bookService: BookService,
private destroyRef: DestroyRef, private destroyRef: DestroyRef,
private toastr: ToastrService,
) { ) {
this.fontFamilies = this.bookService.getFontFamilies().map(f => f.title); this.fontFamilies = this.bookService.getFontFamilies().map(f => f.title);
this.cdRef.markForCheck(); this.cdRef.markForCheck();
@ -222,6 +224,7 @@ export class ManageReadingProfilesComponent implements OnInit {
}, },
error: err => { error: err => {
console.log(err); console.log(err);
this.toastr.error(err.message);
} }
}) })
} else { } else {
@ -236,6 +239,7 @@ export class ManageReadingProfilesComponent implements OnInit {
}, },
error: err => { error: err => {
console.log(err); console.log(err);
this.toastr.error(err.message);
} }
}) })
} }
@ -246,8 +250,9 @@ export class ManageReadingProfilesComponent implements OnInit {
private packData(): ReadingProfile { private packData(): ReadingProfile {
const data: ReadingProfile = this.readingProfileForm!.getRawValue(); const data: ReadingProfile = this.readingProfileForm!.getRawValue();
data.id = this.selectedProfile!.id; data.id = this.selectedProfile!.id;
// Hack around readerMode being sent as a string otherwise // Hack around readerMode being sent as a string otherwise ????
data.readerMode = parseInt(data.readerMode as unknown as string); data.readerMode = parseInt(data.readerMode as unknown as string);
data.bookReaderLayoutMode = parseInt(data.bookReaderLayoutMode as unknown as string);
return data; return data;
} }