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

[Feature/Sample] Loading Screen #480

Closed
bakes82 opened this issue Aug 23, 2023 · 4 comments · Fixed by #482
Closed

[Feature/Sample] Loading Screen #480

bakes82 opened this issue Aug 23, 2023 · 4 comments · Fixed by #482
Assignees
Labels
Enhancement New feature or request

Comments

@bakes82
Copy link
Contributor

bakes82 commented Aug 23, 2023

LoadingScreen

LoadingScreen.razor (Create new)

@using Blazor.Server.UI.Services.Layout
@inherits LayoutComponentBase

@if (_isLoaded)
{
    @ChildContent
}
else
{
    var randomNumber = new Random().Next(-45, -15) + "%";
    var randomNumber2 = new Random().Next(10, 30) + "%";
    <div id="app">
        <style>
            @@keyframes slide {
                0% {
                    transform: translateX(@randomNumber);
                }
                100% {
                    transform: translateY(@randomNumber2);
                }
            }

            .loadScreen-animation {
                animation: slide 3s ease-in-out infinite alternate;
                bottom: 0;
                left: -50%;
                opacity: .5;
                position: fixed;
                right: -50%;
                top: 0;
                z-index: -1;
            }

            .loadScreen-animation-cont {
                left: 50%;
                padding: 10vmin;
                position: fixed;
                text-align: center;
                top: 50%;
                transform: translate(-50%, -50%);
            }
            
            svg {
            	position: fixed;
            	top: 50%;
            	left: 50%;
            	transform: translate(-50%, -50%);
            	height: 150px;
            	width: 150px;
            }
        </style>

        <div style="height:100%;width:100%;margin:0;position:fixed;background-color:@(LayoutService.IsDarkMode ? LayoutService.CurrentTheme.PaletteDark.Background : LayoutService.CurrentTheme.Palette.Background)">
            <div class="loadScreen-animation"></div>
            <div class="loadScreen-animation" style="@Gradient animation-direction:alternate-reverse;animation-duration:2s;"></div>
            <div class="loadScreen-animation" style="@Gradient animation-duration:5s;"></div>
            <div class="loadScreen-animation-cont">
                <svg viewBox="0 0 100 100">
                    <g fill="none" stroke="@(LayoutService.IsDarkMode ? LayoutService.CurrentTheme.PaletteDark.Primary : LayoutService.CurrentTheme.Palette.Primary)" stroke-linecap="round" stroke-linejoin="round" stroke-width="6">
                        <!-- left line -->
                        <path d="M 21 40 V 59">
                            <animateTransform
                                attributeName="transform"
                                attributeType="XML"
                                type="rotate"
                                values="0 21 59; 180 21 59"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <!-- right line -->
                        <path d="M 79 40 V 59">
                            <animateTransform
                                attributeName="transform"
                                attributeType="XML"
                                type="rotate"
                                values="0 79 59; -180 79 59"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <!-- top line -->
                        <path d="M 50 21 V 40">
                            <animate
                                attributeName="d"
                                values="M 50 21 V 40; M 50 59 V 40"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <!-- btm line -->
                        <path d="M 50 60 V 79">
                            <animate
                                attributeName="d"
                                values="M 50 60 V 79; M 50 98 V 79"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <!-- top box -->
                        <path d="M 50 21 L 79 40 L 50 60 L 21 40 Z">
                            <animate
                                attributeName="stroke"
                                values="rgba(255,255,255,1); rgba(100,100,100,0)"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <!-- mid box -->
                        <path d="M 50 40 L 79 59 L 50 79 L 21 59 Z"/>
                        <!-- btm box -->
                        <path d="M 50 59 L 79 78 L 50 98 L 21 78 Z">
                            <animate
                                attributeName="stroke"
                                values="rgba(100,100,100,0); rgba(255,255,255,1)"
                                dur="2s"
                                repeatCount="indefinite"/>
                        </path>
                        <animateTransform
                            attributeName="transform"
                            attributeType="XML"
                            type="translate"
                            values="0 0; 0 -19"
                            dur="2s"
                            repeatCount="indefinite"/>
                    </g>
                </svg>
            </div>
        </div>
    </div>
}

@code {

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public LayoutService LayoutService { get; set; }
    
    [Parameter]
    public int LoadingDelayMs { get; set; }

    private bool _isLoaded;

    private string Gradient => $"background-image: linear-gradient(-120deg, {(LayoutService.IsDarkMode ? LayoutService.CurrentTheme.PaletteDark.Background : LayoutService.CurrentTheme.Palette.Background)} 50%, {(LayoutService.IsDarkMode ? LayoutService.CurrentTheme.PaletteDark.Surface : LayoutService.CurrentTheme.Palette.Surface)} 50%);";

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(LoadingDelayMs);
        _isLoaded = true;
    }

}

App.razor (Modify)

@using Blazor.Server.UI.Services.Layout

@inject IStringLocalizer<SharedResource> L
<Fluxor.Blazor.Web.StoreInitializer />
<LoadingScreen LayoutService="LayoutService" LoadingDelayMs="3000">
<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <Authorizing>
                    <text>@L["Please wait, we are authorizing you..."]</text>
                </Authorizing>
                <NotAuthorized>
                    @if (@context.User.Identity?.IsAuthenticated??false)
                    {
                        <p>@L["You are not authorized to be here. For more information, contact your system administrator."]</p>
                    }
                    else
                    {
                        <Login />
                    }
                </NotAuthorized>
            </AuthorizeRouteView>

        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="d-flex" >
                    <p role="alert">@L["Sorry, there's nothing at this address."] <MudButton Variant="Variant.Filled" Size="Size.Small" Link="/">@L["Go Home"]</MudButton></p>
                </MudContainer>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>
</LoadingScreen>
@code{
    [Inject] private LayoutService LayoutService { get; set; }
    
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        LayoutService.SetBaseTheme(Theme.Theme.ApplicationTheme());
        await LayoutService.ApplyUserPreferences(true);
    }
}
@neozhu
Copy link
Owner

neozhu commented Aug 24, 2023

This feature is really cool. Could you push a PR (Pull Request) for this change?

@Bram1903 Bram1903 linked a pull request Aug 24, 2023 that will close this issue
@Bram1903
Copy link
Collaborator

Hello @bakes82,

This is a copy of the message from the above mentioned PR, but unfortunately, Neozhu already merged that PR, so we can further discuss the changes here, and perhaps create a new PR when necessary.

I want to express my gratitude for your assistance – it has been incredibly valuable. The loading screen component you've crafted is truly impressive, and I'm thoroughly impressed with its design.

I'd like to bring up a couple of points for consideration. Currently, the loading screen lacks user customization options, specifically the ability for administrators to choose whether they want to enable or disable it, as well as the option to adjust the duration it remains visible. This level of flexibility would be quite beneficial, given the variability in server performance. Of course, you already added the duration parameter as an option, but this cannot be set without touching the code itself, or I have overlooked something 😇.

On a related note, I've already incorporated the customization features for enabling/disabling the loading screen and modifying its duration within this pull request.

On a different topic, I've encountered a bit of a puzzle. When users who aren't logged in attempt to do so, they encounter the waiting screen – which makes sense. However, after a successful login, the loading screen reappears. My assumption is that our internal authentication controller might be responsible, potentially due to browser redirection and forceful reloading to ensure data accuracy. If it's possible within your availability, could you please look into this issue? The goal is to streamline the experience so that non-logged-in users don't encounter the loading screen twice.

Additionally, I've been wondering if the content behind the loading screen is actually rendering components. Currently, it seems like the loading screen is displayed without any real content rendering until the loading screen is finished. This becomes evident when I toggle the loading screen on or off – the time it takes for me to be logged in remains the same, as indicated by the loading icon in the top left corner where your username is displayed. While a purely cosmetic loading screen might be unnecessary, I might be overlooking something, or my device is too quick to be able to see a difference in rendering.

Thank you for your dedication and expertise in addressing these matters.

Kind regards,
Bram

@bakes82
Copy link
Contributor Author

bakes82 commented Aug 24, 2023

The loading screen isn't designed to be customized w/out code, per se. I did implement your enable flag and other tweaks, so it can be used like a more generic blocker. It's just a component like everything else, you can choose to use it or not. Yes its cosmetic, you can see data loading behind the screen, it's more to make the transitions between pages flow a bit better, you might not like it or want to use it. Why I didnt originally do as a PR. For me and my application users the hard screen loading w/out a transition feels more abrupt/clunky, so on pages where you do data loads, it can obscure the initial loading or make it appear shorter because of the transition, even though if there was no loading screen it would be the same amount of time just a different loading animation and they think oh the data is already there thats fast ;) Im not a UX designer, but I know some of the basic principles and if showing a animation/loading screen tends to give the perception of things being faster even if its not

@Bram1903 Bram1903 added the Enhancement New feature or request label Aug 30, 2023
@Bram1903
Copy link
Collaborator

Implemented!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants