Picsur/frontend/src/app/routes/view/view.component.ts

241 lines
6.8 KiB
TypeScript
Raw Normal View History

2022-02-28 22:18:07 +00:00
import { Component, OnInit } from '@angular/core';
2022-03-06 11:34:33 +00:00
import { ActivatedRoute, Router } from '@angular/router';
2022-09-01 11:38:33 +00:00
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
2022-06-27 13:23:06 +00:00
import { ImageLinks } from 'picsur-shared/dist/dto/image-links.class';
2022-04-25 22:02:37 +00:00
import {
2022-08-27 12:24:26 +00:00
AnimFileType,
FileType,
ImageFileType,
2022-09-06 14:32:16 +00:00
SupportedFileTypeCategory,
2022-04-25 22:02:37 +00:00
} from 'picsur-shared/dist/dto/mimes.dto';
2022-09-01 11:38:33 +00:00
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
2022-08-27 12:24:26 +00:00
2022-05-02 13:03:01 +00:00
import { EImage } from 'picsur-shared/dist/entities/image.entity';
import { EUser } from 'picsur-shared/dist/entities/user.entity';
2022-04-25 22:02:37 +00:00
import { HasFailed, HasSuccess } from 'picsur-shared/dist/types';
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
2022-08-27 12:24:26 +00:00
import { ParseFileType } from 'picsur-shared/dist/util/parse-mime';
2022-03-16 14:59:06 +00:00
import { ImageService } from 'src/app/services/api/image.service';
2022-09-01 11:38:33 +00:00
import { PermissionService } from 'src/app/services/api/permission.service';
import { UserService } from 'src/app/services/api/user.service';
import { Logger } from 'src/app/services/logger/logger.service';
import { DialogService } from 'src/app/util/dialog-manager/dialog.service';
import { DownloadService } from 'src/app/util/download-manager/download.service';
import { ErrorService } from 'src/app/util/error-manager/error.service';
import { UtilService } from 'src/app/util/util.service';
2022-06-05 18:38:20 +00:00
import {
CustomizeDialogComponent,
2022-09-06 14:32:16 +00:00
CustomizeDialogData,
2022-06-05 18:38:20 +00:00
} from './customize-dialog/customize-dialog.component';
2022-02-28 22:18:07 +00:00
@Component({
templateUrl: './view.component.html',
styleUrls: ['./view.component.scss'],
})
export class ViewComponent implements OnInit {
private readonly logger = new Logger(ViewComponent.name);
2022-02-28 22:18:07 +00:00
constructor(
2022-06-27 15:37:37 +00:00
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly imageService: ImageService,
2022-09-01 11:38:33 +00:00
private readonly permissionService: PermissionService,
private readonly userService: UserService,
private readonly errorService: ErrorService,
private readonly downloadService: DownloadService,
private readonly dialogService: DialogService,
private readonly utilService: UtilService,
2022-02-28 22:18:07 +00:00
) {}
2022-04-25 22:02:37 +00:00
private id: string;
private hasOriginal: boolean = false;
2022-08-27 12:24:26 +00:00
private masterFileType: FileType = {
identifier: ImageFileType.JPEG,
category: SupportedFileTypeCategory.Image,
2022-04-25 22:02:37 +00:00
};
2022-08-27 12:24:26 +00:00
private currentSelectedFormat: string = ImageFileType.JPEG;
2022-04-25 22:02:37 +00:00
public formatOptions: {
value: string;
key: string;
}[] = [];
2022-08-27 12:24:26 +00:00
public setSelectedFormat: string = ImageFileType.JPEG;
2022-04-25 22:02:37 +00:00
2022-04-25 16:07:36 +00:00
public previewLink = '';
2022-04-05 18:37:25 +00:00
public imageLinks = new ImageLinks();
2022-02-28 22:18:07 +00:00
2022-05-02 13:03:01 +00:00
public image: EImage | null = null;
public imageUser: EUser | null = null;
2022-09-01 11:38:33 +00:00
public canDelete: boolean = false;
2022-02-28 22:18:07 +00:00
async ngOnInit() {
2022-09-01 11:38:33 +00:00
this.subscribePermissions();
// Extract and verify params
2022-02-28 22:18:07 +00:00
const params = this.route.snapshot.paramMap;
2022-04-25 22:02:37 +00:00
this.id = params.get('id') ?? '';
if (!UUIDRegex.test(this.id)) {
return this.errorService.quitError('Invalid image link', this.logger);
2022-02-28 22:18:07 +00:00
}
2022-09-01 11:38:33 +00:00
// Get metadata
2022-04-25 22:02:37 +00:00
const metadata = await this.imageService.GetImageMeta(this.id);
if (HasFailed(metadata))
return this.errorService.quitFailure(metadata, this.logger);
2022-02-28 22:18:07 +00:00
// Get width of screen in pixels
const width = window.innerWidth * window.devicePixelRatio;
2022-09-01 11:38:33 +00:00
// Populate fields with metadata
this.previewLink =
this.imageService.GetImageURL(this.id, metadata.fileTypes.master) +
(width > 1 ? `?width=${width}&shrinkonly=yes` : '');
2022-04-25 16:07:36 +00:00
2022-08-27 12:24:26 +00:00
this.hasOriginal = metadata.fileTypes.original !== undefined;
2022-04-25 22:02:37 +00:00
2022-05-02 13:03:01 +00:00
this.imageUser = metadata.user;
this.image = metadata.image;
2022-09-01 11:38:33 +00:00
// Populate default selected format
2022-08-27 12:24:26 +00:00
const masterFiletype = ParseFileType(metadata.fileTypes.master);
if (HasSuccess(masterFiletype)) {
this.masterFileType = masterFiletype;
2022-04-25 22:02:37 +00:00
}
2022-08-27 12:24:26 +00:00
if (this.masterFileType.category === SupportedFileTypeCategory.Image) {
this.setSelectedFormat = ImageFileType.JPEG;
} else if (
this.masterFileType.category === SupportedFileTypeCategory.Animation
) {
this.setSelectedFormat = AnimFileType.GIF;
2022-04-25 22:02:37 +00:00
} else {
2022-08-27 12:24:26 +00:00
this.setSelectedFormat = metadata.fileTypes.master;
2022-04-25 22:02:37 +00:00
}
2022-05-12 10:06:37 +00:00
this.selectedFormat(this.setSelectedFormat);
2022-04-25 22:02:37 +00:00
this.updateFormatOptions();
2022-09-01 11:38:33 +00:00
this.updatePermissions();
2022-04-25 22:02:37 +00:00
}
selectedFormat(format: string) {
2022-05-12 10:06:37 +00:00
this.currentSelectedFormat = format;
2022-04-25 22:02:37 +00:00
if (format === 'original') {
this.imageLinks = this.imageService.CreateImageLinksFromID(this.id, null);
} else {
this.imageLinks = this.imageService.CreateImageLinksFromID(
this.id,
2022-06-05 10:20:16 +00:00
format,
2022-04-25 22:02:37 +00:00
);
}
2022-04-16 14:35:28 +00:00
}
2022-04-19 10:40:17 +00:00
download() {
this.downloadService.downloadFile(this.imageLinks.source);
2022-02-28 22:18:07 +00:00
}
2022-03-01 19:41:55 +00:00
share() {
this.downloadService.shareFile(this.imageLinks.source);
}
2022-09-01 11:38:33 +00:00
goBackHome() {
this.router.navigate(['/']);
}
async deleteImage() {
const pressedButton = await this.dialogService.showDialog({
2022-09-01 11:38:33 +00:00
title: `Are you sure you want to delete the image?`,
description: 'This action cannot be undone.',
buttons: [
{
name: 'cancel',
text: 'Cancel',
},
{
color: 'warn',
name: 'delete',
text: 'Delete',
},
],
});
if (pressedButton === 'delete') {
const result = await this.imageService.DeleteImage(this.id);
if (HasFailed(result))
return this.errorService.showFailure(result, this.logger);
2022-09-01 11:38:33 +00:00
this.errorService.success('Image deleted');
2022-09-01 11:38:33 +00:00
this.router.navigate(['/']);
}
}
2022-05-12 10:06:37 +00:00
async customize() {
2022-06-05 18:38:20 +00:00
const options: CustomizeDialogData = {
imageID: this.id,
selectedFormat: this.currentSelectedFormat,
formatOptions: this.utilService.getBaseFormatOptions(),
2022-06-05 18:38:20 +00:00
};
if (options.selectedFormat === 'original') {
2022-08-27 12:24:26 +00:00
options.selectedFormat = this.masterFileType.identifier;
2022-06-05 18:38:20 +00:00
}
await this.dialogService.showCustomDialog(
CustomizeDialogComponent,
options,
{
dismissable: false,
},
);
2022-05-12 10:06:37 +00:00
}
2022-09-01 11:38:33 +00:00
@AutoUnsubscribe()
private subscribePermissions() {
return this.permissionService.live.subscribe(
this.updatePermissions.bind(this),
);
}
private updatePermissions() {
const permissions = this.permissionService.snapshot;
if (permissions.includes(Permission.ImageAdmin)) {
this.canDelete = true;
return;
}
if (this.imageUser === null) return;
if (
permissions.includes(Permission.ImageUpload) &&
this.imageUser.id === this.userService.snapshot?.id
) {
this.canDelete = true;
return;
}
this.canDelete = false;
2022-03-01 19:41:55 +00:00
}
2022-04-25 22:02:37 +00:00
private updateFormatOptions() {
let newOptions: {
value: string;
key: string;
}[] = [];
if (this.hasOriginal) {
newOptions.push({
value: 'Original',
key: 'original',
});
}
newOptions = newOptions.concat(this.utilService.getBaseFormatOptions());
2022-06-05 18:38:20 +00:00
this.formatOptions = newOptions;
}
2022-02-28 22:18:07 +00:00
}