diff --git a/backend/downloader.js b/backend/downloader.js index 7fd8703..14e224e 100644 --- a/backend/downloader.js +++ b/backend/downloader.js @@ -545,7 +545,7 @@ async function getVideoInfoByURL(url, args = [], download_uid = null) { const error = `Error while retrieving info on video with URL ${url} with the following message: output JSON could not be parsed. Output JSON: ${output}`; logger.error(error); if (download_uid) { - await db_api.updateRecord('download_queue', {uid: download_uid}, {error: error, paused: true, running: false}); + await db_api.updateRecord('download_queue', {uid: download_uid}, {error: error, finished: true, running: false}); } resolve(null); } @@ -556,7 +556,7 @@ async function getVideoInfoByURL(url, args = [], download_uid = null) { } if (download_uid) { const error = 'Failed to get info, see server logs for specific error.'; - await db_api.updateRecord('download_queue', {uid: download_uid}, {error: err.stderr ? err.stderr : error, paused: true, running: false}); + await db_api.updateRecord('download_queue', {uid: download_uid}, {error: err.stderr ? err.stderr : error, finished: true, running: false}); } resolve(null); } diff --git a/src/app/components/downloads/downloads.component.html b/src/app/components/downloads/downloads.component.html index e9458f8..015268f 100644 --- a/src/app/components/downloads/downloads.component.html +++ b/src/app/components/downloads/downloads.component.html @@ -61,7 +61,8 @@ - + + diff --git a/src/app/components/downloads/downloads.component.ts b/src/app/components/downloads/downloads.component.ts index c253130..6b4cedb 100644 --- a/src/app/components/downloads/downloads.component.ts +++ b/src/app/components/downloads/downloads.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, ViewChild, Input } from '@angular/core'; +import { Component, OnInit, OnDestroy, ViewChild, Input, EventEmitter } from '@angular/core'; import { PostsService } from 'app/posts.services'; import { trigger, transition, animateChild, stagger, query, style, animate } from '@angular/animations'; import { Router } from '@angular/router'; @@ -7,6 +7,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialog.component'; import { MatSort } from '@angular/material/sort'; +import { Clipboard } from '@angular/cdk/clipboard'; @Component({ selector: 'app-downloads', @@ -54,10 +55,10 @@ export class DownloadsComponent implements OnInit, OnDestroy { running_download_exists = false; STEP_INDEX_TO_LABEL = { - 0: 'Creating download', - 1: 'Getting info', - 2: 'Downloading file', - 3: 'Complete' + 0: $localize`Creating download`, + 1: $localize`Getting info`, + 2: $localize`Downloading file`, + 3: $localize`Complete` } displayedColumns: string[] = ['date', 'title', 'stage', 'subscription', 'progress', 'actions']; @@ -72,7 +73,7 @@ export class DownloadsComponent implements OnInit, OnDestroy { return result; } - constructor(public postsService: PostsService, private router: Router, private dialog: MatDialog) { } + constructor(public postsService: PostsService, private router: Router, private dialog: MatDialog, private clipboard: Clipboard) { } ngOnInit(): void { if (this.postsService.initialized) { @@ -229,6 +230,27 @@ export class DownloadsComponent implements OnInit, OnDestroy { return downloads_old; } + + showError(download) { + const copyToClipboardEmitter = new EventEmitter(); + this.dialog.open(ConfirmDialogComponent, { + data: { + dialogTitle: $localize`Error for ${download['url']}:url:`, + dialogText: download['error'], + submitText: $localize`Copy to clipboard`, + cancelText: $localize`Close`, + closeOnSubmit: false, + onlyEmitOnDone: true, + doneEmitter: copyToClipboardEmitter + } + }); + copyToClipboardEmitter.subscribe(done => { + if (done) { + this.postsService.openSnackBar($localize`Copied to clipboard!`); + this.clipboard.copy(download['error']); + } + }); + } } export interface Download { diff --git a/src/app/dialogs/confirm-dialog/confirm-dialog.component.html b/src/app/dialogs/confirm-dialog/confirm-dialog.component.html index ddfde17..278e750 100644 --- a/src/app/dialogs/confirm-dialog/confirm-dialog.component.html +++ b/src/app/dialogs/confirm-dialog/confirm-dialog.component.html @@ -11,5 +11,8 @@ - + \ No newline at end of file diff --git a/src/app/dialogs/confirm-dialog/confirm-dialog.component.ts b/src/app/dialogs/confirm-dialog/confirm-dialog.component.ts index 31ec18a..815d30e 100644 --- a/src/app/dialogs/confirm-dialog/confirm-dialog.component.ts +++ b/src/app/dialogs/confirm-dialog/confirm-dialog.component.ts @@ -11,18 +11,23 @@ export class ConfirmDialogComponent implements OnInit { dialogTitle = 'Confirm'; dialogText = 'Would you like to confirm?'; submitText = 'Yes' + cancelText = null; submitClicked = false; + closeOnSubmit = true; - doneEmitter: EventEmitter = null; + doneEmitter: EventEmitter = null; onlyEmitOnDone = false; warnSubmitColor = false; constructor(@Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: MatDialogRef) { - if (this.data.dialogTitle) { this.dialogTitle = this.data.dialogTitle }; - if (this.data.dialogText) { this.dialogText = this.data.dialogText }; - if (this.data.submitText) { this.submitText = this.data.submitText }; - if (this.data.warnSubmitColor) { this.warnSubmitColor = this.data.warnSubmitColor }; + if (this.data.dialogTitle !== undefined) { this.dialogTitle = this.data.dialogTitle } + if (this.data.dialogText !== undefined) { this.dialogText = this.data.dialogText } + if (this.data.submitText !== undefined) { this.submitText = this.data.submitText } + if (this.data.cancelText !== undefined) { this.cancelText = this.data.cancelText } + if (this.data.warnSubmitColor !== undefined) { this.warnSubmitColor = this.data.warnSubmitColor } + if (this.data.warnSubmitColor !== undefined) { this.warnSubmitColor = this.data.warnSubmitColor } + if (this.data.closeOnSubmit !== undefined) { this.closeOnSubmit = this.data.closeOnSubmit } // checks if emitter exists, if so don't autoclose as it should be handled by caller if (this.data.doneEmitter) { @@ -34,9 +39,9 @@ export class ConfirmDialogComponent implements OnInit { confirmClicked() { if (this.onlyEmitOnDone) { this.doneEmitter.emit(true); - this.submitClicked = true; + if (this.closeOnSubmit) this.submitClicked = true; } else { - this.dialogRef.close(true); + if (this.closeOnSubmit) this.dialogRef.close(true); } } diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts index bf56ae8..996d819 100644 --- a/src/app/main/main.component.ts +++ b/src/app/main/main.component.ts @@ -915,11 +915,15 @@ export class MainComponent implements OnInit { this.current_download = res['download']; this.percentDownloaded = this.current_download.percent_complete; - if (this.current_download['finished']) { + if (this.current_download['finished'] && !this.current_download['error']) { const container = this.current_download['container']; const is_playlist = this.current_download['file_uids'].length > 1; this.downloadHelper(container, this.current_download['type'], is_playlist, false); this.current_download = null; + } else if (this.current_download['finished'] && this.current_download['error']) { + this.downloadingfile = false; + this.current_download = null; + this.openSnackBar('Download failed!', 'OK.'); } } else { // console.log('failed to get new download');