frontend: Added share link into the layout when only one participant is joined

- enhance share meeting link component with dynamic title, subtitle, and additional info
This commit is contained in:
Carlos Santos 2025-07-31 16:18:42 +02:00
parent f6c5ecf6ef
commit 37375186d4
7 changed files with 98 additions and 10 deletions

View File

@ -1,5 +1,13 @@
<div class="meeting-url-badge fade-in-delayed-more">
<div class="meeting-url-badge-title">Invite others with this meeting link</div>
<div class="meeting-url-badge">
@if (title) {
<div class="meeting-url-badge-title" [class]="[titleSize, titleWeight]">{{ title }}</div>
}
@if (subtitle) {
<div class="meeting-url-badge-subtitle">
{{ subtitle }}
</div>
}
<div class="meeting-url-badge-container" (click)="copyClicked.emit()">
<span class="meeting-url-text">{{ meetingUrl }}</span>
@ -7,4 +15,8 @@
<mat-icon>content_copy</mat-icon>
</button>
</div>
@if (additionalInfo) {
<div class="meeting-url-badge-additional-info">{{ additionalInfo }}</div>
}
</div>

View File

@ -6,8 +6,41 @@
text-align: center;
font-size: var(--ov-meet-font-size-sm);
font-weight: var(--ov-meet-font-weight-light);
color: var(--ov-meet-text-primary);
color: var(--ov-meet-text-on-surface);
margin-bottom: var(--ov-meet-spacing-sm);
&.sm {
font-size: var(--ov-meet-font-size-sm);
}
&.md {
font-size: var(--ov-meet-font-size-md);
}
&.lg {
font-size: var(--ov-meet-font-size-lg);
}
&.xl {
font-size: var(--ov-meet-font-size-xl);
}
&.light {
font-weight: var(--ov-meet-font-weight-light);
}
&.semibold {
font-weight: var(--ov-meet-font-weight-semibold);
}
&.bold {
font-weight: var(--ov-meet-font-weight-bold);
}
&.normal {
font-weight: var(--ov-meet-font-weight-normal);
}
}
.meeting-url-badge-subtitle{
text-align: center;
font-size: var(--ov-meet-font-size-md);
color: var(--ov-meet-text-on-surface);
margin: var(--ov-meet-spacing-sm);
}
.meeting-url-badge-container {
@include ov-flex-center;
@ -29,7 +62,7 @@
.meeting-url-text {
font-family: var(--ov-meet-font-family-mono, 'Roboto Mono', monospace);
font-size: var(--ov-meet-font-size-sm);
color: var(--ov-meet-text-secondary);
color: var(--ov-meet-text-on-surface);
font-weight: var(--ov-meet-font-weight-medium);
letter-spacing: 0.025em;
user-select: none;

View File

@ -1,6 +1,4 @@
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { Output, EventEmitter } from '@angular/core';
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { MatButtonModule, MatIconButton } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
@ -12,6 +10,11 @@ import { MatIconModule } from '@angular/material/icon';
styleUrl: './share-meeting-link.component.scss'
})
export class ShareMeetingLinkComponent {
@Input() meetingUrl!: string;
@Output() copyClicked = new EventEmitter<void>();
@Input() meetingUrl!: string;
@Input() title: string = 'Invite others with this meeting link';
@Input() titleSize: 'sm' | 'md' | 'lg' | 'xl' = 'sm';
@Input() titleWeight: 'light' | 'semibold' | 'bold' | 'normal' = 'normal';
@Input() subtitle?: string;
@Input() additionalInfo?: string;
@Output() copyClicked = new EventEmitter<void>();
}

View File

@ -100,6 +100,21 @@
></ov-share-meeting-link>
</div>
</div>
<ng-container *ovLayoutAdditionalElements>
@if (remoteParticipants.length === 0) {
<div class="main-share-meeting-link-container fade-in-delayed-more">
<ov-share-meeting-link
[title]="'Start collaborating'"
[subtitle]="'Share this link to bring others into the meeting'"
[titleSize]="'xl'"
[titleWeight]="'bold'"
[meetingUrl]="hostname + '/' + roomId"
(copyClicked)="copyPublisherLink()"
></ov-share-meeting-link>
</div>
}
</ng-container>
}
</ov-videoconference>
} @else {

View File

@ -218,6 +218,14 @@
padding: 10px;
}
.main-share-meeting-link-container {
background-color: var(--ov-meet-surface-color);
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--ov-meet-radius-md);
}
// Responsive adjustments
@include ov-mobile-down {
.room-access-container {

View File

@ -44,12 +44,14 @@ import {
ParticipantLeftEvent,
ParticipantLeftReason,
ParticipantModel,
ParticipantService,
RecordingStartRequestedEvent,
RecordingStopRequestedEvent,
RemoteParticipant,
Room,
RoomEvent
} from 'openvidu-components-angular';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-meeting',
@ -89,11 +91,14 @@ export class MeetingComponent implements OnInit {
participantName = '';
participantToken = '';
participantRole: ParticipantRole = ParticipantRole.PUBLISHER;
remoteParticipants: ParticipantModel[] = [];
showMeeting = false;
features: Signal<ApplicationFeatures>;
meetingEndedByMe = false;
private destroy$ = new Subject<void>();
constructor(
protected route: ActivatedRoute,
protected navigationService: NavigationService,
@ -104,6 +109,7 @@ export class MeetingComponent implements OnInit {
protected meetingService: MeetingService,
protected openviduService: OpenViduService,
protected participantService: ParticipantTokenService,
protected componentParticipantService: ParticipantService,
protected appDataService: AppDataService,
protected wcManagerService: WebComponentManagerService,
protected sessionStorageService: SessionStorageService,
@ -128,6 +134,11 @@ export class MeetingComponent implements OnInit {
await this.initializeParticipantName();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* Sets the back button text based on the application mode and user role
*/
@ -238,6 +249,12 @@ export class MeetingComponent implements OnInit {
await this.addParticipantNameToUrl();
await this.roomService.loadPreferences(this.roomId);
this.showMeeting = true;
// Subscribe to remote participants updates for showing/hiding the share meeting link component
this.componentParticipantService.remoteParticipants$
.pipe(takeUntil(this.destroy$))
.subscribe((participants) => {
this.remoteParticipants = participants;
});
} catch (error) {
console.error('Error accessing meeting:', error);
}

View File

@ -19,7 +19,7 @@
--ov-meet-text-on-primary: #ffffff;
--ov-meet-text-on-secondary: #ffffff;
--ov-meet-text-on-accent: #ffffff;
--ov-meet-text-on-surface: #212121;
--ov-meet-text-on-surface: #494949;
--ov-meet-text-on-background: #212121;
// === SHADOWS - LIGHT THEME ===