Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve data loading and caching in Boilerplate (#9515) #9516

Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
@inherits AppComponentBase

@{
var imageUrl = user.ProfileImageName is null ? null : $"{profileImageUrl}&file={user.ProfileImageName}";
}
@inherits AppComponentBase

<section>
<BitDropMenu Transparent @bind-IsOpen="isOpen" Responsive
OnDismiss="() => showCultures = false"
Classes="@(new() { Callout="user-menu-callout" })">
<Template>
<BitPersona Class="persona"
ImageUrl="@imageUrl"
ImageUrl="@ProfileImageUrl"
[email protected]
PrimaryText="@user.DisplayName"
Classes="@(new() { DetailsContainer="persona-details" })"
Expand All @@ -23,7 +19,7 @@
{
<BitStack AutoSize>
<BitPersona Class="persona"
ImageUrl="@imageUrl"
ImageUrl="@ProfileImageUrl"
OnImageClick="GoToProfile"
Size="BitPersonaSize.Size48"
PrimaryText="@user.DisplayName"
Expand All @@ -40,15 +36,18 @@
@Localizer[nameof(AppStrings.ProfileTitle)]
</BitActionButton>

<BitActionButton IconName="@BitIconName.Globe" FullWidth OnClick="() => showCultures=true">
<BitStack Horizontal Gap="0" Grows VerticalAlign="BitAlignment.Center">
@Localizer[nameof(AppStrings.Language)]
<BitSpacer />
<BitIcon Size="BitSize.Small"
Color="BitColor.SecondaryForeground"
IconName="@(currentDir is BitDir.Rtl ? BitIconName.ChevronLeft : BitIconName.ChevronRight)" />
</BitStack>
</BitActionButton>
@if (CultureInfoManager.MultilingualEnabled)
{
<BitActionButton IconName="@BitIconName.Globe" FullWidth OnClick="() => showCultures=true">
<BitStack Horizontal Gap="0" Grows VerticalAlign="BitAlignment.Center">
@Localizer[nameof(AppStrings.Language)]
<BitSpacer />
<BitIcon Size="BitSize.Small"
Color="BitColor.SecondaryForeground"
IconName="@(currentDir is BitDir.Rtl ? BitIconName.ChevronLeft : BitIconName.ChevronRight)" />
</BitStack>
</BitActionButton>
}

<BitStack Horizontal VerticalAlign="BitAlignment.Center" Gap="0">
<BitActionButton Style="flex-grow:1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public partial class UserMenu
private bool isOpen;
private bool showCultures;
private UserDto user = new();
private string? profileImageUrl;
private bool isSignOutConfirmOpen;
private Action unsubscribeUerDataUpdated = default!;
private BitChoiceGroupItem<string>[] cultures = default!;
Expand All @@ -24,6 +23,9 @@ public partial class UserMenu
[CascadingParameter(Name = Parameters.CurrentTheme)] private AppThemeType? currentTheme { get; set; }


private string? ProfileImageUrl => user.GetProfileImageUrl(AbsoluteServerAddress);


protected override async Task OnInitAsync()
{
if (CultureInfoManager.MultilingualEnabled)
Expand All @@ -44,9 +46,6 @@ protected override async Task OnInitAsync()

user = await userController.GetCurrentUser(CurrentCancellationToken);

var accessToken = await PrerenderStateService.GetValue(AuthTokenProvider.GetAccessToken);
profileImageUrl = new Uri(AbsoluteServerAddress, $"/api/Attachment/GetProfileImage?access_token={accessToken}").ToString();

await base.OnInitAsync();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
@inherits AppComponentBase

@{
var imageUrl = User?.ProfileImageName is null ? null : $"{profileImageUrl}&file={User.ProfileImageName}";
}

<section>
<BitStack HorizontalAlign="BitAlignment.Center">
@if (Loading)
Expand Down Expand Up @@ -32,7 +28,7 @@
@if (isUploading is false)
{
<BitPersona HidePersonaDetails
ImageUrl="@imageUrl"
ImageUrl="@ProfileImageUrl"
PrimaryText="@User?.FullName"
[email protected]
Presence="@(IsOnline is null ? BitPersonaPresence.None : IsOnline is true ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ public partial class ProfileSection

private bool isSaving;
private bool isUploading;
private string? profileImageUrl;
private string? profileImageUploadUrl;
private string? removeProfileImageHttpUrl;
private BitFileUpload fileUploadRef = default!;
private readonly EditUserDto editUserDto = new();


private string? ProfileImageUrl => User?.GetProfileImageUrl(AbsoluteServerAddress);


protected override async Task OnInitAsync()
{
var accessToken = await PrerenderStateService.GetValue(AuthTokenProvider.GetAccessToken);

removeProfileImageHttpUrl = $"api/Attachment/RemoveProfileImage?access_token={accessToken}";

profileImageUrl = new Uri(AbsoluteServerAddress, $"/api/Attachment/GetProfileImage?access_token={accessToken}").ToString();
profileImageUploadUrl = new Uri(AbsoluteServerAddress, $"/api/Attachment/UploadProfileImage?access_token={accessToken}").ToString();

await base.OnInitAsync();
Expand Down Expand Up @@ -74,7 +72,7 @@ private async Task RemoveProfileImage()

try
{
await HttpClient.DeleteAsync(removeProfileImageHttpUrl, CurrentCancellationToken);
await HttpClient.DeleteAsync("api/Attachment/RemoveProfileImage", CurrentCancellationToken);

User.ProfileImageName = null;

Expand All @@ -98,7 +96,7 @@ private async Task HandleOnUploadComplete()
{
var updatedUser = await userController.GetCurrentUser(CurrentCancellationToken);

User.ProfileImageName = updatedUser.ProfileImageName;
updatedUser.Patch(User);

PublishUserDataUpdated();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@

<PageTitle>@Localizer[nameof(AppStrings.SettingsPageTitle)]</PageTitle>

@{
var imageUrl = user?.ProfileImageName is null ? null : $"{profileImageUrl}&file={user.ProfileImageName}";
}

<section>
<BitStack Class="stack">
<Accordion @bind-Value="@openedAccordion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public partial class SettingsPage

private UserDto? user;
private bool isLoading;
private string? profileImageUrl;
private string? openedAccordion;


Expand All @@ -30,10 +29,7 @@ protected override async Task OnInitAsync()

try
{
user = user = (await PrerenderStateService.GetValue(() => HttpClient.GetFromJsonAsync("api/User/GetCurrentUser", JsonSerializerOptions.GetTypeInfo<UserDto>(), CurrentCancellationToken)))!;

var accessToken = await PrerenderStateService.GetValue(AuthTokenProvider.GetAccessToken);
profileImageUrl = new Uri(AbsoluteServerAddress, $"/api/Attachment/GetProfileImage?access_token={accessToken}").ToString();
user = (await PrerenderStateService.GetValue(() => HttpClient.GetFromJsonAsync("api/User/GetCurrentUser", JsonSerializerOptions.GetTypeInfo<UserDto>(), CurrentCancellationToken)))!;
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,71 +23,71 @@
<BitStack>
<BitText Typography="BitTypography.H5">Statistics</BitText>
<BitPivot Style="width:100%" Styles="@(new() { Body = "overflow:auto" })">
<BitPivotItem HeaderText="GitHub">
@if (isLoadingGitHub)
<BitPivotItem HeaderText="Nuget">
@if (isLoadingNuget)
{
<BitStack HorizontalAlign="BitAlignment.Center">
<BitRippleLoading />
</BitStack>
}
else if (gitHubStats is not null)
else if (nugetStats is not null)
{
var data = nugetStats.Data[0];
<BitStack>
<BitStack Horizontal>
<BitText>Name:</BitText>
<BitText><b>@gitHubStats.Name</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Total stars:</BitText>
<BitText><b>@gitHubStats.StargazersCount.ToString("N0")</b></BitText>
<BitText>Package id:</BitText>
<BitText><b>@data.Id</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Forks count:</BitText>
<BitText><b>@gitHubStats.ForksCount.ToString("N0")</b></BitText>
<BitText>Version:</BitText>
<BitText><b>@data.Version</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Repo:</BitText>
<BitLink Target="_blank"
Href="https://github.com/bitfoundation/bitplatform/tree/develop/src/Templates/Boilerplate">
<BitImage Alt="bitplatform GitHub stars"
Src="https://img.shields.io/github/stars/bitfoundation/bitplatform?style=social&label=Github%20%E2%9C%A8" />
</BitLink>
<BitText>Total downloads:</BitText>
<BitText><b>@data.TotalDownloads.ToString("N0")</b></BitText>
</BitStack>
</BitStack>
}
else
{
<BitText Typography="BitTypography.H4">GitHub stats could not be loaded.</BitText>
<BitText Typography="BitTypography.H4">Nuget stats could not be loaded.</BitText>
}
</BitPivotItem>
<BitPivotItem HeaderText="Nuget">
@if (isLoadingNuget)
<BitPivotItem HeaderText="GitHub">
@if (isLoadingGitHub)
{
<BitStack HorizontalAlign="BitAlignment.Center">
<BitRippleLoading />
</BitStack>
}
else if (nugetStats is not null)
else if (gitHubStats is not null)
{
var data = nugetStats.Data[0];
<BitStack>
<BitStack Horizontal>
<BitText>Package id:</BitText>
<BitText><b>@data.Id</b></BitText>
<BitText>Name:</BitText>
<BitText><b>@gitHubStats.Name</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Version:</BitText>
<BitText><b>@data.Version</b></BitText>
<BitText>Total stars:</BitText>
<BitText><b>@gitHubStats.StargazersCount.ToString("N0")</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Total downloads:</BitText>
<BitText><b>@data.TotalDownloads.ToString("N0")</b></BitText>
<BitText>Forks count:</BitText>
<BitText><b>@gitHubStats.ForksCount.ToString("N0")</b></BitText>
</BitStack>
<BitStack Horizontal>
<BitText>Repo:</BitText>
<BitLink Target="_blank"
Href="https://github.com/bitfoundation/bitplatform/tree/develop/src/Templates/Boilerplate">
<BitImage Alt="bitplatform GitHub stars"
Src="https://img.shields.io/github/stars/bitfoundation/bitplatform?style=social&label=Github%20%E2%9C%A8" />
</BitLink>
</BitStack>
</BitStack>
}
else
{
<BitText Typography="BitTypography.H4">Nuget stats could not be loaded.</BitText>
<BitText Typography="BitTypography.H4">GitHub stats could not be loaded.</BitText>
}
</BitPivotItem>
</BitPivot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,41 @@ protected override async Task OnInitAsync()
// However, the logic in other HTTP message handlers, such as **LoggingDelegatingHandler** and **RetryDelegatingHandler**,
// effectively addresses most scenarios.

await Task.WhenAll(LoadGitHub(), LoadNuget());
await Task.WhenAll(LoadNuget(), LoadGitHub());
}

private async Task LoadGitHub()
private async Task LoadNuget()
{
try
{
gitHubStats = await statisticsController.GetGitHubStats(CurrentCancellationToken);
nugetStats = await statisticsController.GetNugetStats(packageId: "Bit.BlazorUI", CurrentCancellationToken);
}
finally
{
isLoadingGitHub = false;
isLoadingNuget = false;
await InvokeAsync(StateHasChanged);
}
}

private async Task LoadNuget()
private async Task LoadGitHub()
{
try
{
nugetStats = await statisticsController.GetNugetStats(packageId: "Bit.BlazorUI", CurrentCancellationToken);
// GitHub results (2nd Bit Pivot tab) aren't shown by default and aren't critical for SEO,
// so we can skip it in pre-rendering to save time.
if (InPrerenderSession is false)
{
gitHubStats = await statisticsController.GetGitHubStats(CurrentCancellationToken);
}
}
catch
{
// GetGitHubStats method calls the GitHub API directly from the client.
// We've intentionally ignored proper exception handling to keep this example simple.
}
finally
{
isLoadingNuget = false;
isLoadingGitHub = false;
await InvokeAsync(StateHasChanged);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Boilerplate.Client.Core.Data
public partial class OfflineDbContextModel
{
private OfflineDbContextModel()
: base(skipDetectChanges: false, modelId: new Guid("b97b95bd-89b9-4be0-a574-d2035391c0c8"), entityTypeCount: 1)
: base(skipDetectChanges: false, modelId: new Guid("4b5524a2-4b87-4b64-9e87-fe2649512808"), entityTypeCount: 1)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
"Boilerplate.Shared.Dtos.Identity.UserDto",
typeof(UserDto),
baseEntityType,
propertyCount: 9,
propertyCount: 10,
keyCount: 1);

var id = runtimeEntityType.AddProperty(
Expand All @@ -41,6 +41,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
nullable: true,
valueConverter: new DateTimeOffsetToBinaryConverter());

var concurrencyStamp = runtimeEntityType.AddProperty(
"ConcurrencyStamp",
typeof(string),
propertyInfo: typeof(UserDto).GetProperty("ConcurrencyStamp", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(UserDto).GetField("<ConcurrencyStamp>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
nullable: true);

var email = runtimeEntityType.AddProperty(
"Email",
typeof(string),
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading