diff --git a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.html b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.html index 8ac5133..204f709 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.html +++ b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.html @@ -1,21 +1,42 @@

Share Recording

- - Private (authenticated users) - Public (anyone with the link) - + @if (!recordingUrl) { + @if (erroMessage) { +
+ error + {{ erroMessage }} +
+ } -
- -
+ + Public (anyone with the link) + Private (authenticated users) + + +
+ @if (loading) { + + } @else { + + } +
+ } @if (recordingUrl) {
Shareable URL -
diff --git a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.scss b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.scss index 079ec8c..a3ed118 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.scss @@ -3,6 +3,7 @@ flex-direction: column; gap: 20px; min-width: 100%; + overflow: hidden; mat-radio-group { display: flex; @@ -10,20 +11,26 @@ gap: 10px; mat-radio-button { - color: var(--ov-text-primary-color); + color: var(--ov-text-surface-color); } } } -.generate-btn-container { +.error-text { display: flex; - justify-content: flex-start; + align-items: center; + gap: 6px; + color: var(--ov-error-color); + font-weight: 500; +} + +.generate-btn-container { + align-self: flex-start; } .recording-url-container { - display: flex; - flex-direction: column; - gap: 10px; + width: 100%; + margin-top: 8px; } .url-field { @@ -31,6 +38,6 @@ input { font-size: 14px; - color: var(--ov-text-primary-color); + color: var(--ov-text-surface-color); } } diff --git a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.ts b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.ts index af65efd..20c7902 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/components/dialogs/share-recording-dialog/share-recording-dialog.component.ts @@ -1,3 +1,4 @@ +import { Clipboard } from '@angular/cdk/clipboard'; import { Component, Inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; @@ -11,7 +12,9 @@ import { import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatRadioModule } from '@angular/material/radio'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { HttpService } from 'shared-meet-components'; @Component({ @@ -27,29 +30,56 @@ import { HttpService } from 'shared-meet-components'; MatDialogTitle, MatDialogContent, MatDialogActions, - MatDialogClose + MatDialogClose, + MatTooltipModule, + MatProgressSpinnerModule ], templateUrl: './share-recording-dialog.component.html', styleUrl: './share-recording-dialog.component.scss' }) export class ShareRecordingDialogComponent { - accessType: 'private' | 'public' = 'private'; - recordingUrl: string | undefined; + accessType: 'private' | 'public' = 'public'; + recordingUrl?: string; + + loading = false; + erroMessage?: string; + copied = false; constructor( - @Inject(MAT_DIALOG_DATA) public data: { recordingId: string }, - private httpService: HttpService - ) {} + @Inject(MAT_DIALOG_DATA) public data: { recordingId: string; recordingUrl?: string }, + private httpService: HttpService, + private clipboard: Clipboard + ) { + this.recordingUrl = data.recordingUrl; + } async getRecordingUrl() { - const privateAccess = this.accessType === 'private'; - const { url } = await this.httpService.generateRecordingUrl(this.data.recordingId, privateAccess); - this.recordingUrl = url; + this.loading = true; + this.erroMessage = undefined; + + try { + const privateAccess = this.accessType === 'private'; + const { url } = await this.httpService.generateRecordingUrl(this.data.recordingId, privateAccess); + this.recordingUrl = url; + } catch (error) { + this.erroMessage = 'Failed to generate recording URL. Please try again later.'; + console.error('Error generating recording URL:', error); + } finally { + this.loading = false; + } } copyToClipboard() { - if (this.recordingUrl) { - navigator.clipboard.writeText(this.recordingUrl); + if (!this.recordingUrl) { + return; } + + this.clipboard.copy(this.recordingUrl!); + this.copied = true; + + // Reset copied state after 2 seconds + setTimeout(() => { + this.copied = false; + }, 2000); } }