feat(mpv-player-bar): add MPV player bar component with process management UI

This commit is contained in:
4gray committed 2024-12-16 01:38:19 +01:00
1 parent 1827afb783
commit 744a63f327
3 files changed
+190

No files matched your search

@@ -0,0 +1,51 @@
<div class="mpv-player-bar" *ngIf="(activeProcesses$ | async)?.length">
@for (process of activeProcesses$ | async; track process.id) {
<div class="player-item">
<div class="player-media">
@if (process.thumbnail) {
<img
[src]="process.thumbnail"
[alt]="process.title"
class="media-thumbnail"
(error)="
$event.target.src =
'./assets/images/default-poster.png'
"
/>
} @else {
<div class="media-thumbnail-placeholder">
<mat-icon>live_tv</mat-icon>
</div>
}
<div class="media-info">
<span class="media-title">{{ process.title }}</span>
<span class="media-url">{{ process.url }}</span>
</div>
</div>
<div class="player-controls">
<!-- <button
mat-icon-button
(click)="pauseStream(process.id)"
title="Pause"
>
<mat-icon>pause</mat-icon>
</button>
<button
mat-icon-button
(click)="playStream(process.id)"
title="Play"
>
<mat-icon>play_arrow</mat-icon>
</button> -->
<button
mat-icon-button
(click)="closeStream(process.id)"
title="Close"
>
<mat-icon>close</mat-icon>
</button>
</div>
</div>
}
</div>
@@ -0,0 +1,103 @@
.mpv-player-bar {
background: #282828;
color: white;
padding: 16px;
box-shadow: 0 -2px 20px rgba(0, 0, 0, 0.3);
flex-shrink: 0; // Prevent shrinking
}
.player-items {
display: flex;
flex-direction: column;
gap: 8px;
}
.player-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
height: 56px;
}
.player-info {
display: flex;
flex-direction: column;
}
.player-title {
font-size: 14px;
font-weight: 500;
}
.player-url {
font-size: 12px;
color: #a0a0a0;
margin-top: 4px;
}
.player-media {
display: flex;
align-items: center;
gap: 16px;
flex: 1;
}
.media-thumbnail {
width: 56px;
height: 56px;
object-fit: cover;
border-radius: 4px;
}
.media-thumbnail-placeholder {
width: 56px;
height: 56px;
background: #404040;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
mat-icon {
font-size: 24px;
color: #b3b3b3;
}
}
.media-info {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.media-title {
font-size: 14px;
font-weight: 500;
color: #fff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.media-url {
font-size: 12px;
color: #b3b3b3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.player-controls {
display: flex;
align-items: center;
gap: 8px;
button {
color: #fff;
&:hover {
color: #1db954;
}
}
}
@@ -0,0 +1,36 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { Observable } from 'rxjs';
import {
MpvPlayerService,
MpvProcess,
} from '../../services/mpv-player.service';
@Component({
standalone: true,
imports: [CommonModule, MatIconModule, MatButtonModule],
selector: 'app-mpv-player-bar',
templateUrl: './mpv-player-bar.component.html',
styleUrls: ['./mpv-player-bar.component.scss'],
})
export class MpvPlayerBarComponent {
activeProcesses$: Observable<MpvProcess[]>;
constructor(private mpvPlayerService: MpvPlayerService) {
this.activeProcesses$ = this.mpvPlayerService.activeProcesses$;
}
async closeStream(processId: number): Promise<void> {
await this.mpvPlayerService.closeStream(processId);
}
/* async playStream(processId: number): Promise<void> {
await this.mpvPlayerService.playStream(processId);
}
async pauseStream(processId: number): Promise<void> {
await this.mpvPlayerService.pauseStream(processId);
} */
}