From c1155e59699313237bddfa414d5e361dd0812c7f Mon Sep 17 00:00:00 2001 From: Corbin Crutchley Date: Sun, 25 Jan 2026 01:21:32 -0800 Subject: [PATCH] feat: improve UI for no-song selected --- src/app/components/album-art/album-art.html | 4 +- src/app/components/album-art/album-art.ts | 11 +- .../controls/play-pause/play-pause-btn.html | 16 +-- .../controls/play-pause/play-pause-btn.scss | 5 +- .../controls/play-pause/play-pause.html | 18 ++- .../controls/play-pause/play-pause.ts | 2 + src/app/injectables/metadata.ts | 2 +- .../currently-playing/currently-playing.html | 113 ++++++++---------- .../currently-playing/currently-playing.ts | 21 +++- src/assets/library_icon.svg | 3 + 10 files changed, 110 insertions(+), 85 deletions(-) create mode 100644 src/assets/library_icon.svg diff --git a/src/app/components/album-art/album-art.html b/src/app/components/album-art/album-art.html index 728115d..7fb1cd4 100644 --- a/src/app/components/album-art/album-art.html +++ b/src/app/components/album-art/album-art.html @@ -1,5 +1,5 @@
-
+
-
+
diff --git a/src/app/components/album-art/album-art.ts b/src/app/components/album-art/album-art.ts index a018da1..bd403f2 100644 --- a/src/app/components/album-art/album-art.ts +++ b/src/app/components/album-art/album-art.ts @@ -1,4 +1,5 @@ -import { Component, input } from "@angular/core"; +import { Component, computed, input } from "@angular/core"; +import { defaultCover } from "../../injectables/metadata"; @Component({ selector: "album-art", @@ -7,4 +8,12 @@ import { Component, input } from "@angular/core"; }) export class AlbumArt { src = input(); + + srcOrDefault = computed(() => { + const srcData = this.src(); + if (!srcData) { + return `url(${defaultCover})`; + } + return srcData; + }); } diff --git a/src/app/components/controls/play-pause/play-pause-btn.html b/src/app/components/controls/play-pause/play-pause-btn.html index 2fefc6f..b92036d 100644 --- a/src/app/components/controls/play-pause/play-pause-btn.html +++ b/src/app/components/controls/play-pause/play-pause-btn.html @@ -8,14 +8,14 @@ " > @if (isPaused()) { - - Play + + Play } @else { - - Pause + + Pause } diff --git a/src/app/components/controls/play-pause/play-pause-btn.scss b/src/app/components/controls/play-pause/play-pause-btn.scss index db402f9..9f943da 100644 --- a/src/app/components/controls/play-pause/play-pause-btn.scss +++ b/src/app/components/controls/play-pause/play-pause-btn.scss @@ -1,4 +1,3 @@ - :host { display: inline-flex; height: 1px; @@ -25,8 +24,8 @@ /* Blur + Shadow Big */ box-shadow: - 0px 7px 10px 0px rgba(0, 0, 0, 0.05), - 0px 40px 80px 0px rgba(0, 0, 0, 0.08); + 0px 7px 10px 0px rgba(0, 0, 0, 0.05), + 0px 40px 80px 0px rgba(0, 0, 0, 0.08); } .playPauseIcon { diff --git a/src/app/components/controls/play-pause/play-pause.html b/src/app/components/controls/play-pause/play-pause.html index 82b6afb..a3342b6 100644 --- a/src/app/components/controls/play-pause/play-pause.html +++ b/src/app/components/controls/play-pause/play-pause.html @@ -5,16 +5,22 @@ }}" > + + @if (isPlayingASong()) { + + } diff --git a/src/app/components/controls/play-pause/play-pause.ts b/src/app/components/controls/play-pause/play-pause.ts index 038bf35..5034bbf 100644 --- a/src/app/components/controls/play-pause/play-pause.ts +++ b/src/app/components/controls/play-pause/play-pause.ts @@ -13,5 +13,7 @@ export class PlayPause { resumeit = output(); pauseit = output(); volumeClick = output(); + pickSong = output(); isPaused = input.required(); + isPlayingASong = input.required(); } diff --git a/src/app/injectables/metadata.ts b/src/app/injectables/metadata.ts index 25b91d1..ef1da23 100644 --- a/src/app/injectables/metadata.ts +++ b/src/app/injectables/metadata.ts @@ -6,7 +6,7 @@ import { invoke } from "@tauri-apps/api/core"; import { SongMetadata } from "../types/song-metadata"; import { Vibrant } from "node-vibrant/browser"; -const defaultCover = "url('/assets/default_album_art.svg')"; +export const defaultCover = "/assets/default_album_art.svg"; // TODO: Remove this in favor of using the `@reduxjs/toolkit` package and RTK Query (not out yet for Angular) @Injectable({ providedIn: null }) diff --git a/src/app/views/currently-playing/currently-playing.html b/src/app/views/currently-playing/currently-playing.html index 2cc4300..f30fc45 100644 --- a/src/app/views/currently-playing/currently-playing.html +++ b/src/app/views/currently-playing/currently-playing.html @@ -1,70 +1,61 @@
- @if (!openFileMutation.data()) { - - } - - @if ( - openFileMutation.data() && - stateMetadata.metadata.isSuccess() && - openFileMutation.isSuccess() - ) { - -
-
-

- {{ - stateMetadata.metadata.data()?.tags?.TrackTitle ?? - "Unknown Title" - }} -

-

- {{ - stateMetadata.metadata.data()?.tags?.Artist ?? - "Unknown Artist" - }} -

-

- {{ - stateMetadata.metadata.data()?.tags?.Album ?? "Unknown Album" - }} -

-
+ @if ( stateMetadata.metadata.isSuccess()) { + +
+
+

+ {{ stateMetadata.metadata.data()?.tags?.TrackTitle ?? "Unknown Title" + }} +

+

+ {{ stateMetadata.metadata.data()?.tags?.Artist ?? "Unknown Artist" }} +

+

+ {{ stateMetadata.metadata.data()?.tags?.Album ?? "Unknown Album" }} +

+
-
-
-

{{ currentTimeFormatted() }}

-

{{ totalTimeFormatted() }}

-
- - +
+
+

{{ currentTimeFormatted() }}

+

{{ totalTimeFormatted() }}

+ + +
-
- @if (controls() === "volume-change") { - - } @else { - - } -
+
+ @if (controls() === "volume-change") { + + } @else { + + }
+
+ } @else if (stateMetadata.metadata.isLoading()) { +

Loading...

+ } @else { +

An error has occurred...

}
diff --git a/src/app/views/currently-playing/currently-playing.ts b/src/app/views/currently-playing/currently-playing.ts index c2fccc9..a075494 100644 --- a/src/app/views/currently-playing/currently-playing.ts +++ b/src/app/views/currently-playing/currently-playing.ts @@ -29,7 +29,7 @@ export class CurrentlyPlaying { mutationFn: async () => { const path = await pickSong(); if (!path) { - return; + return false; } await play(path); return true; @@ -93,8 +93,23 @@ export class CurrentlyPlaying { return `${showHours ? hours + ":" : ""}${showMinutes ? zeroPad(minutes, 2) : ""}:${zeroPad(seconds, 2)}`; }); - resume = resume; - pause = pause; + isPlayingASong = computed(() => !!this.playingMetadata().currentlyPlayingPath); + + resume = () => { + // Need to select a file to play + if (!this.isPlayingASong()) { + this.openFileMutation.mutate(undefined, { + onSuccess: () => { + void resume(); + }, + }); + return; + } + void resume(); + }; + pause = () => { + void pause(); + }; seekFromInput(event: Event) { const input = event.target as HTMLInputElement; diff --git a/src/assets/library_icon.svg b/src/assets/library_icon.svg new file mode 100644 index 0000000..de5c8ca --- /dev/null +++ b/src/assets/library_icon.svg @@ -0,0 +1,3 @@ + + + -- 2.51.2