mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
adding loadingbar
This commit is contained in:
parent
85505970b7
commit
5da852b711
@ -3,6 +3,7 @@ import {AuthenticationService} from "./model/network/authentication.service";
|
|||||||
import {UserDTO} from "../../common/entities/UserDTO";
|
import {UserDTO} from "../../common/entities/UserDTO";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pi-gallery2-app',
|
selector: 'pi-gallery2-app',
|
||||||
template: `<router-outlet></router-outlet>`,
|
template: `<router-outlet></router-outlet>`,
|
||||||
@ -31,4 +32,6 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import {ThumbnailManagerService} from "./gallery/thumnailManager.service";
|
|||||||
import {OverlayService} from "./gallery/overlay.service";
|
import {OverlayService} from "./gallery/overlay.service";
|
||||||
import {Config} from "../../common/config/public/Config";
|
import {Config} from "../../common/config/public/Config";
|
||||||
import {LAZY_MAPS_API_CONFIG} from "@agm/core/services";
|
import {LAZY_MAPS_API_CONFIG} from "@agm/core/services";
|
||||||
|
import {SlimLoadingBarModule} from "ng2-slim-loading-bar";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -49,7 +50,8 @@ export class GoogleMapsConfig {
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
appRoutes,
|
appRoutes,
|
||||||
AgmCoreModule.forRoot()
|
AgmCoreModule.forRoot(),
|
||||||
|
SlimLoadingBarModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [AppComponent,
|
declarations: [AppComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
|
9
frontend/app/frame/frame.component.css
Normal file
9
frontend/app/frame/frame.component.css
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.navbar {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ng2-slim-loading-bar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,34 @@
|
|||||||
<nav class="navbar navbar-inverse navbar-static-top">
|
<nav class="navbar navbar-inverse navbar-static-top">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
|
||||||
aria-expanded="false" aria-controls="navbar">
|
aria-expanded="false" aria-controls="navbar">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">Toggle navigation</span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="#"><img src="assets/icon_inv.png" style="max-height: 26px; display: inline;"/> PiGallery2</a>
|
<a class="navbar-brand" href="#"><img src="assets/icon_inv.png" style="max-height: 26px; display: inline;"/>
|
||||||
</div>
|
PiGallery2</a>
|
||||||
<div id="navbar" class="collapse navbar-collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="active"><a [routerLink]="['/gallery','/']">Gallery</a></li>
|
|
||||||
<li><a [routerLink]="['/admin']">Admin</a></li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right" *ngIf="authenticationRequired">
|
|
||||||
<li>
|
|
||||||
<p class="navbar-text" *ngIf="user">{{user.name}}</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a style="cursor: pointer" (click)="logout()">Logout</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ng-content select="[navbar]"></ng-content>
|
|
||||||
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="navbar" class="collapse navbar-collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="active"><a [routerLink]="['/gallery','/']">Gallery</a></li>
|
||||||
|
<li><a [routerLink]="['/admin']">Admin</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right" *ngIf="authenticationRequired">
|
||||||
|
<li>
|
||||||
|
<p class="navbar-text" *ngIf="user">{{user.name}}</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a style="cursor: pointer" (click)="logout()">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ng-content select="[navbar]"></ng-content>
|
||||||
|
|
||||||
|
</div><!--/.nav-collapse -->
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
<ng2-slim-loading-bar></ng2-slim-loading-bar>
|
||||||
<ng-content select="[body]"></ng-content>
|
<ng-content select="[body]"></ng-content>
|
||||||
|
@ -7,6 +7,7 @@ import {Config} from "../../../common/config/public/Config";
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-frame',
|
selector: 'app-frame',
|
||||||
templateUrl: './frame.component.html',
|
templateUrl: './frame.component.html',
|
||||||
|
styleUrls: ['./frame.component.css'],
|
||||||
providers: [RouterLink],
|
providers: [RouterLink],
|
||||||
encapsulation: ViewEncapsulation.Emulated
|
encapsulation: ViewEncapsulation.Emulated
|
||||||
})
|
})
|
||||||
|
@ -48,60 +48,12 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.thumbnail = this.thumbnailService.getThumbnail(this.gridPhoto);
|
this.thumbnail = this.thumbnailService.getThumbnail(this.gridPhoto);
|
||||||
/* this.loading.show = true;
|
|
||||||
//set up before adding task to thumbnail generator
|
|
||||||
if (this.gridPhoto.isThumbnailAvailable()) {
|
|
||||||
this.image.src = this.gridPhoto.getThumbnailPath();
|
|
||||||
this.image.show = true;
|
|
||||||
} else if (this.gridPhoto.isReplacementThumbnailAvailable()) {
|
|
||||||
this.image.src = this.gridPhoto.getReplacementThumbnailPath();
|
|
||||||
this.image.show = true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
ngAfterViewInit() {
|
|
||||||
//schedule change after Angular checks the model
|
|
||||||
if (!this.gridPhoto.isThumbnailAvailable()) {
|
|
||||||
set Timeout(() => {
|
|
||||||
|
|
||||||
let listener: ThumbnailLoadingListener = {
|
|
||||||
onStartedLoading: () => { //onLoadStarted
|
|
||||||
this.loading.animate = true;
|
|
||||||
},
|
|
||||||
onLoad: () => {//onLoaded
|
|
||||||
this.image.src = this.gridPhoto.getThumbnailPath();
|
|
||||||
this.image.show = true;
|
|
||||||
this.loading.show = false;
|
|
||||||
this.thumbnailTask = null;
|
|
||||||
},
|
|
||||||
onError: (error) => {//onError
|
|
||||||
this.thumbnailTask = null;
|
|
||||||
//TODO: handle error
|
|
||||||
//TODO: not an error if its from cache
|
|
||||||
console.error("something bad happened");
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (this.gridPhoto.isReplacementThumbnailAvailable()) {
|
|
||||||
this.thumbnailTask = this.thumbnailService.loadImage(this.gridPhoto, ThumbnailLoadingPriority.medium, listener);
|
|
||||||
} else {
|
|
||||||
this.thumbnailTask = this.thumbnailService.loadImage(this.gridPhoto, ThumbnailLoadingPriority.high, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.thumbnail.destroy();
|
this.thumbnail.destroy();
|
||||||
/*
|
|
||||||
if (this.thumbnailTask != null) {
|
|
||||||
this.thumbnailService.removeTask(this.thumbnailTask);
|
|
||||||
this.thumbnailTask = null;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -112,6 +64,9 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
|||||||
|
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
|
if (this.thumbnail.Available == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let isInView = this.isInView();
|
let isInView = this.isInView();
|
||||||
if (this.wasInView != isInView) {
|
if (this.wasInView != isInView) {
|
||||||
this.wasInView = isInView;
|
this.wasInView = isInView;
|
||||||
|
@ -19,7 +19,8 @@ export class GalleryMapComponent implements OnChanges, IRenderable {
|
|||||||
//TODO: fix zooming
|
//TODO: fix zooming
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.mapPhotos = this.photos.filter(p => {
|
this.mapPhotos = this.photos.filter(p => {
|
||||||
return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData;
|
return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData &&
|
||||||
|
p.metadata.positionData.GPSData.latitude && p.metadata.positionData.GPSData.longitude;
|
||||||
}).map(p => {
|
}).map(p => {
|
||||||
return {
|
return {
|
||||||
latitude: p.metadata.positionData.GPSData.latitude,
|
latitude: p.metadata.positionData.GPSData.latitude,
|
||||||
@ -31,7 +32,6 @@ export class GalleryMapComponent implements OnChanges, IRenderable {
|
|||||||
this.mapCenter = this.mapPhotos[0];
|
this.mapCenter = this.mapPhotos[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
click() {
|
click() {
|
||||||
|
@ -30,6 +30,7 @@ export abstract class ThumbnailBase {
|
|||||||
protected available: boolean = false;
|
protected available: boolean = false;
|
||||||
protected src: string = null;
|
protected src: string = null;
|
||||||
protected loading: boolean = false;
|
protected loading: boolean = false;
|
||||||
|
protected error: boolean = true;
|
||||||
protected onLoad: Function = null;
|
protected onLoad: Function = null;
|
||||||
protected thumbnailTask: ThumbnailTaskEntity;
|
protected thumbnailTask: ThumbnailTaskEntity;
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ export class IconThumbnail extends ThumbnailBase {
|
|||||||
constructor(private photo: IconPhoto, thumbnailService: ThumbnailLoaderService) {
|
constructor(private photo: IconPhoto, thumbnailService: ThumbnailLoaderService) {
|
||||||
super(thumbnailService);
|
super(thumbnailService);
|
||||||
this.src = "";
|
this.src = "";
|
||||||
|
this.error = false;
|
||||||
if (this.photo.isIconAvailable()) {
|
if (this.photo.isIconAvailable()) {
|
||||||
this.src = this.photo.getIconPath();
|
this.src = this.photo.getIconPath();
|
||||||
this.available = true;
|
this.available = true;
|
||||||
@ -92,6 +94,8 @@ export class IconThumbnail extends ThumbnailBase {
|
|||||||
},
|
},
|
||||||
onError: (error) => {//onError
|
onError: (error) => {//onError
|
||||||
this.thumbnailTask = null;
|
this.thumbnailTask = null;
|
||||||
|
this.loading = false;
|
||||||
|
this.error = true;
|
||||||
//TODO: handle error
|
//TODO: handle error
|
||||||
//TODO: not an error if its from cache
|
//TODO: not an error if its from cache
|
||||||
console.error("something bad happened");
|
console.error("something bad happened");
|
||||||
|
@ -3,12 +3,13 @@ import {Headers, Http, RequestOptions} from "@angular/http";
|
|||||||
import {Message} from "../../../../common/entities/Message";
|
import {Message} from "../../../../common/entities/Message";
|
||||||
import "rxjs/Rx";
|
import "rxjs/Rx";
|
||||||
|
|
||||||
|
import {SlimLoadingBarService} from "ng2-slim-loading-bar";
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NetworkService {
|
export class NetworkService {
|
||||||
|
|
||||||
_baseUrl = "/api";
|
_baseUrl = "/api";
|
||||||
|
|
||||||
constructor(protected _http: Http) {
|
constructor(protected _http: Http, private slimLoadingBarService: SlimLoadingBarService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private callJson<T>(method: string, url: string, data: any = {}): Promise<T> {
|
private callJson<T>(method: string, url: string, data: any = {}): Promise<T> {
|
||||||
@ -16,17 +17,31 @@ export class NetworkService {
|
|||||||
let headers = new Headers({'Content-Type': 'application/json'});
|
let headers = new Headers({'Content-Type': 'application/json'});
|
||||||
let options = new RequestOptions({headers: headers});
|
let options = new RequestOptions({headers: headers});
|
||||||
|
|
||||||
|
this.slimLoadingBarService.visible = true;
|
||||||
|
this.slimLoadingBarService.start(() => {
|
||||||
|
this.slimLoadingBarService.visible = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const process = (res: any) => {
|
||||||
|
this.slimLoadingBarService.complete();
|
||||||
|
return <Message<any>> res.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const err = (err) => {
|
||||||
|
NetworkService.handleError(err);
|
||||||
|
this.slimLoadingBarService.complete();
|
||||||
|
};
|
||||||
|
|
||||||
if (method == "get" || method == "delete") {
|
if (method == "get" || method == "delete") {
|
||||||
return <any>this._http[method](this._baseUrl + url, options)
|
return <any>this._http[method](this._baseUrl + url, options)
|
||||||
.toPromise()
|
.toPromise()
|
||||||
.then(res => <Message<any>> res.json())
|
.then(process)
|
||||||
.catch(NetworkService.handleError);
|
.catch(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._http[method](this._baseUrl + url, body, options)
|
return this._http[method](this._baseUrl + url, body, options)
|
||||||
.toPromise()
|
.toPromise()
|
||||||
.then((res: any) => <Message<any>> res.json())
|
.then(process)
|
||||||
.catch(NetworkService.handleError);
|
.catch(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
public postJson<T>(url: string, data: any = {}): Promise<T> {
|
public postJson<T>(url: string, data: any = {}): Promise<T> {
|
||||||
|
34
frontend/app/style.css
Normal file
34
frontend/app/style.css
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright (C) 2016 Sergey Akopkokhyants
|
||||||
|
* This project is licensed under the terms of the MIT license.
|
||||||
|
* https://github.com/akserg/ng2-slim-loading-bar
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Styling for the Slim Loading Progress Bar container */
|
||||||
|
.slim-loading-bar {
|
||||||
|
position: fixed;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for the Slim Loading Progress Bar itself */
|
||||||
|
.slim-loading-bar-progress {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 99998;
|
||||||
|
background-color: green;
|
||||||
|
color: green;
|
||||||
|
box-shadow: 0 0 10px 0; /* Inherits the font color */
|
||||||
|
height: 2px;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
/* Add CSS3 styles for transition smoothing */
|
||||||
|
-webkit-transition: all 0.5s ease-in-out;
|
||||||
|
-moz-transition: all 0.5s ease-in-out;
|
||||||
|
-o-transition: all 0.5s ease-in-out;
|
||||||
|
transition: all 0.5s ease-in-out;
|
||||||
|
}
|
@ -45,6 +45,7 @@
|
|||||||
"mocha": "^3.4.2",
|
"mocha": "^3.4.2",
|
||||||
"mysql": "^2.13.0",
|
"mysql": "^2.13.0",
|
||||||
"ng2-cookies": "^1.0.12",
|
"ng2-cookies": "^1.0.12",
|
||||||
|
"ng2-slim-loading-bar": "^4.0.0",
|
||||||
"node-iptc": "^1.0.4",
|
"node-iptc": "^1.0.4",
|
||||||
"optimist": "^0.6.1",
|
"optimist": "^0.6.1",
|
||||||
"reflect-metadata": "^0.1.10",
|
"reflect-metadata": "^0.1.10",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user