diff --git a/src-tauri/src/music/commands.rs b/src-tauri/src/music/commands.rs
index 9e213bf..cd3d008 100644
--- a/src-tauri/src/music/commands.rs
+++ b/src-tauri/src/music/commands.rs
@@ -74,6 +74,8 @@ pub fn seek_to(
state: State<'_, AppData>,
) -> Result<(), String> {
core::seek_to(&state, position)?;
+ // Emit the new position immediately so the UI updates without waiting for the next periodic update
+ app.emit("PLAYBACK_POSITION_UPDATE", state.sink.get_pos()).unwrap();
app.emit("SERVER_SYNC_EVENT", "").unwrap();
Ok(())
}
diff --git a/src/app/views/currently-playing.component.ts b/src/app/views/currently-playing.component.ts
index ab63747..2bcf8d2 100644
--- a/src/app/views/currently-playing.component.ts
+++ b/src/app/views/currently-playing.component.ts
@@ -170,13 +170,16 @@ export class AlbumArt {
{{ totalTimeFormatted() }}
-
-
+ [value]="currentSecs() ?? 0"
+ [max]="totalSecs() ?? 0"
+ min="0"
+ step="1"
+ [style.--progress]="progressPercent() + '%'"
+ (input)="seekFromInput($event)"
+ />
@@ -289,22 +292,26 @@ export class AlbumArt {
background-blend-mode: plus-darker;
height: 0.5rem;
appearance: none;
+ background: rgba(0, 0, 0, 0.12);
+ cursor: pointer;
}
- .progressBar::-webkit-progress-bar {
- height: 100%;
- background: rgba(0, 0, 0, 0.12);
- padding: 0;
- margin: 0;
+ .progressBar::-webkit-slider-thumb {
+ appearance: none;
+ width: 0;
+ height: 0;
}
- .progressBar::-webkit-progress-value {
- border-radius: 1.25rem;
- background: rgba(255, 255, 255, 0.8);
- mix-blend-mode: plus-lighter;
- height: 100%;
- padding: 0;
- margin: 0;
+ .progressBar::-webkit-slider-runnable-track {
+ height: 0.5rem;
+ border-radius: 1.5rem;
+ background: linear-gradient(
+ to right,
+ rgba(255, 255, 255, 0.8) 0%,
+ rgba(255, 255, 255, 0.8) var(--progress, 0%),
+ transparent var(--progress, 0%),
+ transparent 100%
+ );
}
`,
],
@@ -335,6 +342,13 @@ export class CurrentlyPlaying {
return this.playingMetadata().position?.secs;
});
+ progressPercent = computed(() => {
+ const current = this.currentSecs() ?? 0;
+ const total = this.totalSecs() ?? 0;
+ if (total === 0) return 0;
+ return (current / total) * 100;
+ });
+
totalTime = computed(() => {
// Format as `hh:mm:ss` but only show minutes and hours if they are non-zero
const duration = this.playingMetadata().duration?.secs;
@@ -380,11 +394,9 @@ export class CurrentlyPlaying {
resume = resume;
pause = pause;
- seekFromProgressBar(event: MouseEvent) {
- const progressBar = event.target as HTMLProgressElement;
- const value =
- (event.offsetX / progressBar.offsetWidth) *
- parseInt(progressBar.getAttribute("max") || "0");
+ seekFromInput(event: Event) {
+ const input = event.target as HTMLInputElement;
+ const value = parseFloat(input.value);
seek(value);
}
}