mirror of
https://github.com/CaramelFur/Picsur.git
synced 2025-11-01 09:55:48 +01:00
add snackbars
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { SnackBarType } from 'src/app/models/snack-bar-type';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
|
||||
@Component({
|
||||
selector: 'copy-field',
|
||||
@@ -11,11 +13,18 @@ export class CopyFieldComponent {
|
||||
@Input() label: string = 'Loading...';
|
||||
@Input() value: string = 'Loading...';
|
||||
|
||||
constructor(private snackBar: MatSnackBar) {}
|
||||
constructor(private utilService: UtilService) {}
|
||||
|
||||
public copy() {
|
||||
try {
|
||||
navigator.clipboard.writeText(this.value);
|
||||
} catch (e) {
|
||||
return this.utilService.showSnackBar(
|
||||
'Copying to clipboard failed',
|
||||
SnackBarType.Error
|
||||
);
|
||||
}
|
||||
|
||||
this.snackBar.open(`Copied ${this.label}!`);
|
||||
this.utilService.showSnackBar(`Copied ${this.label}!`, SnackBarType.Info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CopyFieldComponent } from './copy-field.component';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { UtilModule } from 'src/app/util/util.module';
|
||||
@NgModule({
|
||||
declarations: [CopyFieldComponent],
|
||||
imports: [
|
||||
@@ -12,7 +12,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatSnackBarModule,
|
||||
UtilModule,
|
||||
],
|
||||
exports: [CopyFieldComponent],
|
||||
})
|
||||
|
||||
7
frontend/src/app/models/snack-bar-type.ts
Normal file
7
frontend/src/app/models/snack-bar-type.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export enum SnackBarType {
|
||||
Success = 'snack-success',
|
||||
Error = 'snack-error',
|
||||
Warning = 'snack-warning',
|
||||
Info = 'snack-info',
|
||||
Default = 'snack-default',
|
||||
}
|
||||
@@ -2,10 +2,6 @@ import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { UploadComponent } from '../routes/upload/upload.component';
|
||||
import { NgxDropzoneModule } from 'ngx-dropzone';
|
||||
import {
|
||||
MatSnackBarModule,
|
||||
MAT_SNACK_BAR_DEFAULT_OPTIONS,
|
||||
} from '@angular/material/snack-bar';
|
||||
import { ProcessingComponent } from '../routes/processing/processing.component';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { ApiModule } from '../api/api.module';
|
||||
@@ -14,6 +10,7 @@ import { PageNotFoundComponent } from '../components/pagenotfound/pagenotfound.c
|
||||
import { ViewComponent } from '../routes/view/view.component';
|
||||
import { CopyFieldModule } from '../components/copy-field/copy-field.module';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { UtilModule } from '../util/util.module';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: UploadComponent },
|
||||
@@ -28,7 +25,7 @@ const routes: Routes = [
|
||||
@NgModule({
|
||||
imports: [
|
||||
NgxDropzoneModule,
|
||||
MatSnackBarModule,
|
||||
UtilModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatButtonModule,
|
||||
PageNotFoundModule,
|
||||
@@ -37,16 +34,6 @@ const routes: Routes = [
|
||||
RouterModule.forRoot(routes),
|
||||
],
|
||||
declarations: [UploadComponent, ProcessingComponent, ViewComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
|
||||
useValue: {
|
||||
duration: 2500,
|
||||
horizontalPosition: 'left',
|
||||
panelClass: ['mat-toolbar', 'mat-primary'],
|
||||
},
|
||||
},
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRouterModule {}
|
||||
|
||||
@@ -3,27 +3,30 @@ import { Router } from '@angular/router';
|
||||
import { ProcessingViewMetadata } from 'src/app/models/processing-view-metadata';
|
||||
import { ImageService } from 'src/app/api/image.service';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './processing.component.html',
|
||||
styleUrls: ['./processing.component.scss'],
|
||||
})
|
||||
export class ProcessingComponent implements OnInit {
|
||||
constructor(private router: Router, private imageService: ImageService) {}
|
||||
constructor(
|
||||
private router: Router,
|
||||
private imageService: ImageService,
|
||||
private utilService: UtilService
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
const state = history.state as ProcessingViewMetadata;
|
||||
if (!state) {
|
||||
this.router.navigate(['/'], { replaceUrl: true });
|
||||
return;
|
||||
return this.utilService.quitError('Error');
|
||||
}
|
||||
|
||||
history.replaceState(null, '');
|
||||
|
||||
const hash = await this.imageService.UploadImage(state.imageFile);
|
||||
if (HasFailed(hash)) {
|
||||
this.router.navigate(['/'], { replaceUrl: true });
|
||||
return;
|
||||
return this.utilService.quitError(hash.getReason());
|
||||
}
|
||||
|
||||
this.router.navigate([`/view/`, hash], { replaceUrl: true });
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { NgxDropzoneChangeEvent } from 'ngx-dropzone';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
import { ProcessingViewMetadata } from '../../models/processing-view-metadata';
|
||||
|
||||
@Component({
|
||||
@@ -9,10 +10,10 @@ import { ProcessingViewMetadata } from '../../models/processing-view-metadata';
|
||||
styleUrls: ['./upload.component.scss'],
|
||||
})
|
||||
export class UploadComponent {
|
||||
constructor(private snackBar: MatSnackBar, private router: Router) {}
|
||||
constructor(private utilService: UtilService, private router: Router) {}
|
||||
onSelect(event: NgxDropzoneChangeEvent) {
|
||||
if (event.addedFiles.length > 1) {
|
||||
this.snackBar.open(
|
||||
this.utilService.showSnackBar(
|
||||
'You uploaded multiple images, only one has been uploaded'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
.uploadedimage {
|
||||
max-width: 100%;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.content-border {
|
||||
padding: 2rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { isHash } from 'class-validator';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { ImageService } from 'src/app/api/image.service';
|
||||
import { ImageLinks } from 'picsur-shared/dist/dto/imagelinks.dto';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-view',
|
||||
@@ -15,7 +16,8 @@ export class ViewComponent implements OnInit {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private imageService: ImageService
|
||||
private imageService: ImageService,
|
||||
private utilService: UtilService
|
||||
) {}
|
||||
|
||||
public imageUrl: string;
|
||||
@@ -25,14 +27,12 @@ export class ViewComponent implements OnInit {
|
||||
const params = this.route.snapshot.paramMap;
|
||||
const hash = params.get('hash') ?? '';
|
||||
if (!isHash(hash, 'sha256')) {
|
||||
this.router.navigate(['/'], { replaceUrl: true });
|
||||
return;
|
||||
return this.utilService.quitError('Invalid image link');
|
||||
}
|
||||
|
||||
const imageMeta = await this.imageService.GetImageMeta(hash);
|
||||
if (HasFailed(imageMeta)) {
|
||||
this.router.navigate(['/'], { replaceUrl: true });
|
||||
return;
|
||||
return this.utilService.quitError(imageMeta.getReason());
|
||||
}
|
||||
|
||||
this.imageUrl = this.imageService.GetImageURL(hash);
|
||||
|
||||
24
frontend/src/app/util/util.module.ts
Normal file
24
frontend/src/app/util/util.module.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { UtilService } from './util.service';
|
||||
import {
|
||||
MatSnackBarModule,
|
||||
MAT_SNACK_BAR_DEFAULT_OPTIONS,
|
||||
} from '@angular/material/snack-bar';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
providers: [
|
||||
UtilService,
|
||||
{
|
||||
provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
|
||||
useValue: {
|
||||
duration: 4000,
|
||||
horizontalPosition: 'left',
|
||||
},
|
||||
},
|
||||
],
|
||||
imports: [CommonModule, MatSnackBarModule, RouterModule],
|
||||
})
|
||||
export class UtilModule {}
|
||||
25
frontend/src/app/util/util.service.ts
Normal file
25
frontend/src/app/util/util.service.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { SnackBarType } from '../models/snack-bar-type';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UtilService {
|
||||
constructor(private snackBar: MatSnackBar, private router: Router) {}
|
||||
|
||||
public quitError(message: string) {
|
||||
this.showSnackBar(message, SnackBarType.Error);
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
public showSnackBar(
|
||||
message: string,
|
||||
type: SnackBarType = SnackBarType.Default
|
||||
) {
|
||||
this.snackBar.open(message, '', {
|
||||
panelClass: ['mat-toolbar', 'snackbar', type],
|
||||
});
|
||||
}
|
||||
}
|
||||
2
frontend/src/scss/index.scss
Normal file
2
frontend/src/scss/index.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "./personal.scss";
|
||||
@import "./snackbar.scss";
|
||||
24
frontend/src/scss/snackbar.scss
Normal file
24
frontend/src/scss/snackbar.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
.snackbar {
|
||||
background: #272727;
|
||||
color: white;
|
||||
|
||||
&.snack-success {
|
||||
background: #4d9a51;
|
||||
}
|
||||
|
||||
&.snack-error {
|
||||
background: #d74545;
|
||||
}
|
||||
|
||||
&.snack-warning {
|
||||
background: #f68a1c;
|
||||
}
|
||||
|
||||
&.snack-info {
|
||||
background: #1d95d6;
|
||||
}
|
||||
|
||||
&.snack-default {
|
||||
background: #272727;
|
||||
}
|
||||
}
|
||||
@@ -281,4 +281,4 @@ html {
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
@import "./styles.personal";
|
||||
@import "./scss";
|
||||
|
||||
Reference in New Issue
Block a user