You've already forked pigallery2
mirror of
https://github.com/bpatrik/pigallery2.git
synced 2026-05-16 09:21:12 +02:00
Refactor uploader UI #1118
This commit is contained in:
@@ -81,32 +81,3 @@ app-gallery-map {
|
||||
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
|
||||
}
|
||||
}
|
||||
|
||||
.upload-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.upload-overlay-content {
|
||||
background: var(--bs-body-bg);
|
||||
padding: 2em;
|
||||
text-align: center;
|
||||
border: 2px dashed var(--bs-primary);
|
||||
}
|
||||
|
||||
.upload-progress-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 300px;
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
@@ -25,36 +25,8 @@
|
||||
|
||||
|
||||
<app-gallery-navbar navbar-appendix></app-gallery-navbar>
|
||||
<div body class="container-fluid app-gallery-body" *ngIf="ContentWrapper"
|
||||
[class.upload-over]="isOver">
|
||||
<div class="upload-overlay" *ngIf="isOver">
|
||||
<div class="upload-overlay-content rounded">
|
||||
<div class="upload-overlay-icon">
|
||||
<ng-icon name="ionCloudUploadOutline" size="4em"></ng-icon>
|
||||
</div>
|
||||
<div class="upload-overlay-text" i18n>Drop files to upload</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload-progress-container" *ngIf="uploaderService.uploadProgress.length > 0">
|
||||
<div class="card mb-2" *ngFor="let item of uploaderService.uploadProgress">
|
||||
<div *ngIf="item.lastUpdate > Date.now() - 3000" class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<small class="text-truncate me-2" [title]="item.name">{{ item.name }}</small>
|
||||
<small *ngIf="!item.error">{{ item.progress }}%</small>
|
||||
<small *ngIf="item.error" class="text-danger" [title]="item.error" i18n>Error</small>
|
||||
</div>
|
||||
<div *ngIf="item.error" class="d-flex justify-content-between align-items-center mb-1">
|
||||
<small class="text-danger">{{item.error}}</small>
|
||||
</div>
|
||||
<div class="progress" style="height: 5px;">
|
||||
<div class="progress-bar" role="progressbar"
|
||||
[class.bg-danger]="item.error"
|
||||
[class.bg-success]="item.done && !item.error"
|
||||
[ngStyle]="{'width': item.progress + '%'}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div body class="container-fluid app-gallery-body" *ngIf="ContentWrapper">
|
||||
<app-gallery-uploader [isUploadOver]="isUploadOver"></app-gallery-uploader>
|
||||
<ng-container *ngIf="ContentWrapper.error">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ ContentWrapper.error }}
|
||||
|
||||
@@ -34,6 +34,7 @@ import {SearchQueryUtils} from '../../../../common/SearchQueryUtils';
|
||||
import {UploaderService} from './uploader.service';
|
||||
import {GalleryService} from './gallery.service';
|
||||
import {NgIconComponent} from '@ng-icons/core';
|
||||
import {UploaderComponent} from './upload-progress/upload-progress.gallery.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery',
|
||||
@@ -43,8 +44,6 @@ import {NgIconComponent} from '@ng-icons/core';
|
||||
GalleryLightboxComponent,
|
||||
FrameComponent,
|
||||
NgIf,
|
||||
NgFor,
|
||||
NgStyle,
|
||||
RandomQueryBuilderGalleryComponent,
|
||||
PhotoFrameBuilderGalleryComponent,
|
||||
GalleryNavigatorComponent,
|
||||
@@ -55,7 +54,7 @@ import {NgIconComponent} from '@ng-icons/core';
|
||||
GPXFilesFilterPipe,
|
||||
PhotoFilterPipe,
|
||||
MediaButtonModalComponent,
|
||||
NgIconComponent
|
||||
UploaderComponent
|
||||
]
|
||||
})
|
||||
export class GalleryComponent implements OnInit, OnDestroy {
|
||||
@@ -77,7 +76,6 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
} = null;
|
||||
public readonly mapEnabled: boolean;
|
||||
public directoryContent: GroupedDirectoryContent;
|
||||
public isOver = false;
|
||||
private $counter: Observable<number>;
|
||||
private subscription: { [key: string]: Subscription } = {
|
||||
content: null,
|
||||
@@ -85,6 +83,7 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
timer: null,
|
||||
sorting: null,
|
||||
};
|
||||
public isUploadOver = false;
|
||||
|
||||
constructor(
|
||||
public contentLoader: ContentLoaderService,
|
||||
@@ -187,36 +186,6 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('dragover', ['$event'])
|
||||
onDragOver(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('dragleave', ['$event'])
|
||||
onDragLeave(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isOver = false;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('drop', ['$event'])
|
||||
onDrop(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isOver = false;
|
||||
const files = event.dataTransfer.files;
|
||||
if (files.length > 0) {
|
||||
this.uploaderService.uploadFiles(files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onRoute = async (params: Params): Promise<void> => {
|
||||
const searchQuery = SearchQueryUtils.parseURLifiedQuery(params[QueryParams.gallery.search.query]);
|
||||
@@ -270,5 +239,38 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
};
|
||||
protected readonly Date = Date;
|
||||
|
||||
|
||||
|
||||
@HostListener('dragover', ['$event'])
|
||||
onDragOver(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isUploadOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('dragleave', ['$event'])
|
||||
onDragLeave(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isUploadOver = false;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('drop', ['$event'])
|
||||
onDrop(event: DragEvent): void {
|
||||
if (this.uploaderService.canUpload()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.isUploadOver = false;
|
||||
const files = event.dataTransfer.files;
|
||||
if (files.length > 0) {
|
||||
this.uploaderService.uploadFiles(files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
.upload-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.upload-overlay-content {
|
||||
background: var(--bs-body-bg);
|
||||
padding: 2em;
|
||||
text-align: center;
|
||||
border: 2px dashed var(--bs-primary);
|
||||
}
|
||||
|
||||
.upload-progress-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 300px;
|
||||
z-index: 10001;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="upload-overlay" *ngIf="isUploadOver">
|
||||
<div class="upload-overlay-content rounded">
|
||||
<div class="upload-overlay-icon">
|
||||
<ng-icon name="ionCloudUploadOutline" size="4em"></ng-icon>
|
||||
</div>
|
||||
<div class="upload-overlay-text" i18n>Drop files to upload</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload-progress-container" *ngIf="uploaderService.uploadProgress.length > 0">
|
||||
<div class="card mb-2" *ngFor="let item of uploaderService.uploadProgress">
|
||||
<div *ngIf="item.lastUpdate > Date.now() - 3000" class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<small class="text-truncate me-2" [title]="item.name">{{ item.name }}</small>
|
||||
<small *ngIf="!item.error">{{ item.progress }}%</small>
|
||||
<small *ngIf="item.error" class="text-danger" [title]="item.error" i18n>Error</small>
|
||||
</div>
|
||||
<div *ngIf="item.error" class="d-flex justify-content-between align-items-center mb-1">
|
||||
<small class="text-danger">{{item.error}}</small>
|
||||
</div>
|
||||
<div class="progress" style="height: 5px;">
|
||||
<div class="progress-bar" role="progressbar"
|
||||
[class.bg-danger]="item.error"
|
||||
[class.bg-success]="item.done && !item.error"
|
||||
[ngStyle]="{'width': item.progress + '%'}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
import {Component, HostListener, Input} from '@angular/core';
|
||||
import {NgFor, NgIf, NgStyle} from '@angular/common';
|
||||
import {NgIconComponent} from '@ng-icons/core';
|
||||
import {UploaderService} from '../uploader.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-uploader',
|
||||
templateUrl: './upload-progress.gallery.component.html',
|
||||
styleUrls: ['./upload-progress.gallery.component.css'],
|
||||
imports: [
|
||||
NgIf,
|
||||
NgFor,
|
||||
NgIconComponent,
|
||||
NgStyle,
|
||||
]
|
||||
})
|
||||
export class UploaderComponent {
|
||||
public readonly Date = Date;
|
||||
@Input() isUploadOver: boolean;
|
||||
|
||||
constructor(public uploaderService: UploaderService) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user