diff --git a/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.html b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.html new file mode 100644 index 000000000..db4c44e7a --- /dev/null +++ b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.html @@ -0,0 +1,51 @@ +
+ @for (process of activeProcesses$ | async; track process.id) { +
+
+ @if (process.thumbnail) { + + } @else { +
+ live_tv +
+ } +
+ {{ process.title }} + {{ process.url }} +
+
+ +
+ + +
+
+ } +
diff --git a/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.scss b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.scss new file mode 100644 index 000000000..8720510c9 --- /dev/null +++ b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.scss @@ -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; + } + } +} diff --git a/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.ts b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.ts new file mode 100644 index 000000000..5c0dc8252 --- /dev/null +++ b/src/app/shared/components/mpv-player-bar/mpv-player-bar.component.ts @@ -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; + + constructor(private mpvPlayerService: MpvPlayerService) { + this.activeProcesses$ = this.mpvPlayerService.activeProcesses$; + } + + async closeStream(processId: number): Promise { + await this.mpvPlayerService.closeStream(processId); + } + + /* async playStream(processId: number): Promise { + await this.mpvPlayerService.playStream(processId); + } + + async pauseStream(processId: number): Promise { + await this.mpvPlayerService.pauseStream(processId); + } */ +}