Add loading bars for slow internet

This commit is contained in:
rubikscraft 2022-12-25 23:30:35 +01:00
parent d65ac16943
commit 286333f598
No known key found for this signature in database
GPG Key ID: 1463EBE9200A5CD4
12 changed files with 75 additions and 7 deletions

View File

@ -64,7 +64,7 @@ export class ImageManagerModule implements OnModuleInit, OnModuleDestroy {
this.logger.warn(result.print());
}
this.logger.log(`Cleaned up ${result} derivatives`);
if (result > 0) this.logger.log(`Cleaned up ${result} derivatives`);
}
private async cleanupExpired() {
@ -74,7 +74,8 @@ export class ImageManagerModule implements OnModuleInit, OnModuleDestroy {
this.logger.warn(cleanedUp.print());
}
this.logger.log(`Cleaned up ${cleanedUp} expired images`);
if (cleanedUp > 0)
this.logger.log(`Cleaned up ${cleanedUp} expired images`);
}
onModuleDestroy() {

View File

@ -1,6 +1,7 @@
<app-header
[enableHamburger]="hasSidebar && !isDesktop"
(onHamburgerClick)="sidebar.toggle()"
[loading]="loading"
></app-header>
<mat-sidenav-container class="grow-full">

View File

@ -5,7 +5,8 @@ import {
ActivatedRoute,
NavigationEnd,
NavigationError,
Router,
NavigationStart,
Router
} from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { RouteTransitionAnimations } from './app.animation';
@ -24,6 +25,9 @@ export class AppComponent implements OnInit {
@ViewChild(MatSidenav) sidebar: MatSidenav;
loading: boolean = false;
private loadingTimeout: number | null = null;
wrapContentWithContainer: boolean = true;
sidebarPortal: Portal<any> | undefined = undefined;
@ -54,6 +58,12 @@ export class AppComponent implements OnInit {
@AutoUnsubscribe()
private subscribeRouter() {
return this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
this.loadingStart();
}
if (event instanceof NavigationEnd) {
this.loadingEnd();
}
if (event instanceof NavigationEnd) this.onNavigationEnd(event);
if (event instanceof NavigationError) this.onNavigationError(event);
});
@ -87,6 +97,21 @@ export class AppComponent implements OnInit {
this.updateSidebar();
}
private loadingStart() {
if (this.loadingTimeout !== null) clearTimeout(this.loadingTimeout);
this.loadingTimeout = window.setTimeout(() => {
this.loading = true;
}, 500);
}
private loadingEnd() {
if (this.loadingTimeout !== null) clearTimeout(this.loadingTimeout);
this.loadingTimeout = null;
this.loading = false;
}
private updateSidebar() {
if (!this.sidebar) return;

View File

@ -1,4 +1,11 @@
<mat-toolbar>
<mat-progress-bar
*ngIf="loading"
class="loading-bar"
mode="indeterminate"
color="accent"
></mat-progress-bar>
<button
*ngIf="_enableHamburger"
class="me-3"

View File

@ -55,3 +55,10 @@ mat-toolbar {
box-shadow: 0px 2px 5px -3px rgba(0, 0, 0, 0.2),
0px 5px 8px 0px rgba(0, 0, 0, 0.14), 0px 1px 14px 0px rgba(0, 0, 0, 0.12);
}
.loading-bar {
position: absolute;
top: 64px;
left: 0;
right: 0;
}

View File

@ -5,7 +5,7 @@ import {
EventEmitter,
Input,
OnInit,
Output,
Output
} from '@angular/core';
import { Router } from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
@ -41,6 +41,8 @@ export class HeaderComponent implements OnInit {
public _enableHamburger: boolean = true;
@Output('onHamburgerClick') onHamburgerClick = new EventEmitter<void>();
@Input('loading') public loading: boolean = false;
private currentUser: EUser | null = null;
public canLogIn: boolean = false;

View File

@ -3,6 +3,7 @@ import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { RouterModule } from '@angular/router';
@ -16,6 +17,7 @@ import { HeaderComponent } from './header.component';
MatToolbarModule,
MatButtonModule,
MatProgressBarModule,
RouterModule,
MatIconModule,
MatMenuModule,

View File

@ -30,7 +30,7 @@ export class MasonryComponent implements AfterViewInit, OnDestroy {
this.changeDetector.markForCheck();
}
public _column_count = 1;
@Input('update-speed') update_speed: number = 500;
@Input('update-speed') update_speed: number = 200;
@ContentChildren(MasonryItemDirective)
private content: QueryList<MasonryItemDirective>;

View File

@ -0,0 +1,10 @@
.app-loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.app-loader h1 {
margin-inline: auto;
}

View File

@ -0,0 +1 @@
html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type='button'],[type='reset'],[type='submit'],button{-webkit-appearance:button}[type='button']::-moz-focus-inner,[type='reset']::-moz-focus-inner,[type='submit']::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type='button']:-moz-focusring,[type='reset']:-moz-focusring,[type='submit']:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type='checkbox'],[type='radio']{box-sizing:border-box;padding:0}[type='number']::-webkit-inner-spin-button,[type='number']::-webkit-outer-spin-button{height:auto}[type='search']{-webkit-appearance:textfield;outline-offset:-2px}[type='search']::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}

View File

@ -0,0 +1 @@
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" style="animation:rotator1 5332ms linear infinite both;transform-origin:center" overflow="hidden"><style>@keyframes rotator1{0%{transform:rotate(0deg)}to{transform:rotate(720deg)}}@keyframes rotator2{0%{transform:rotate(0deg)}50.00001%,to{transform:rotate(60deg)}}@keyframes dash{0%{stroke-dashoffset:350}50%{stroke-dashoffset:180;transform:rotate(0deg)}50.00001%{stroke-dashoffset:-71;transform:rotate(-102deg)}to{stroke-dashoffset:-240;transform:rotate(-45deg)}}</style><a style="animation:rotator2 1333ms linear infinite both;transform-origin:center"><circle fill="none" stroke-width="10" cx="50" cy="50" r="40" style="transform-origin:center;animation:dash 1333ms cubic-bezier(.4,0,.2,1) infinite both" stroke-dasharray="360" stroke="#43a047"/></a></svg>

After

Width:  |  Height:  |  Size: 820 B

View File

@ -11,7 +11,8 @@
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/assets/css/normalize.css" />
<link rel="stylesheet" href="/assets/css/loading.css" />
<link rel="stylesheet" href="/assets/css/normalize.min.css" />
<meta name="author" content="Rubikscraft" />
<meta
@ -37,6 +38,16 @@
</head>
<body class="mat-typography mat-app-background">
<noscript>Sorry, but you need javascript</noscript>
<app-root></app-root>
<app-root>
<div class="app-loader">
<img
width="100px"
height="100px"
src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHlsZT0iYW5pbWF0aW9uOnJvdGF0b3IxIDUzMzJtcyBsaW5lYXIgaW5maW5pdGUgYm90aDt0cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciIgb3ZlcmZsb3c9ImhpZGRlbiI+PHN0eWxlPkBrZXlmcmFtZXMgcm90YXRvcjF7MCV7dHJhbnNmb3JtOnJvdGF0ZSgwZGVnKX10b3t0cmFuc2Zvcm06cm90YXRlKDcyMGRlZyl9fUBrZXlmcmFtZXMgcm90YXRvcjJ7MCV7dHJhbnNmb3JtOnJvdGF0ZSgwZGVnKX01MC4wMDAwMSUsdG97dHJhbnNmb3JtOnJvdGF0ZSg2MGRlZyl9fUBrZXlmcmFtZXMgZGFzaHswJXtzdHJva2UtZGFzaG9mZnNldDozNTB9NTAle3N0cm9rZS1kYXNob2Zmc2V0OjE4MDt0cmFuc2Zvcm06cm90YXRlKDBkZWcpfTUwLjAwMDAxJXtzdHJva2UtZGFzaG9mZnNldDotNzE7dHJhbnNmb3JtOnJvdGF0ZSgtMTAyZGVnKX10b3tzdHJva2UtZGFzaG9mZnNldDotMjQwO3RyYW5zZm9ybTpyb3RhdGUoLTQ1ZGVnKX19PC9zdHlsZT48YSBzdHlsZT0iYW5pbWF0aW9uOnJvdGF0b3IyIDEzMzNtcyBsaW5lYXIgaW5maW5pdGUgYm90aDt0cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciI+PGNpcmNsZSBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjEwIiBjeD0iNTAiIGN5PSI1MCIgcj0iNDAiIHN0eWxlPSJ0cmFuc2Zvcm0tb3JpZ2luOmNlbnRlcjthbmltYXRpb246ZGFzaCAxMzMzbXMgY3ViaWMtYmV6aWVyKC40LDAsLjIsMSkgaW5maW5pdGUgYm90aCIgc3Ryb2tlLWRhc2hhcnJheT0iMzYwIiBzdHJva2U9IiM0M2EwNDciLz48L2E+PC9zdmc+Cg=="
/>
<h1>Loading</h1>
</div>
</app-root>
</body>
</html>