From be2fad3190dce256eb2587f73007edfeeee1df06 Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Thu, 10 Apr 2025 19:08:57 -0400 Subject: [PATCH] slowly adding seek bar, now it can increment over time. --- backend/player/player.go | 6 +- frontend/package.json | 2 + frontend/package.json.md5 | 2 +- frontend/pnpm-lock.yaml | 108 ++++++++++++++++++ .../audio-player/seekbar/seek-bar.ts | 74 ++++++++++-- frontend/wailsjs/go/player/Player.d.ts | 6 + frontend/wailsjs/go/player/Player.js | 12 ++ 7 files changed, 199 insertions(+), 11 deletions(-) diff --git a/backend/player/player.go b/backend/player/player.go index 356902b..1be6729 100644 --- a/backend/player/player.go +++ b/backend/player/player.go @@ -174,9 +174,9 @@ func (p *Player) MuteToggle() error { } // return the current position as an int between 0 and 100 to work with progress bar easily. -func (p *Player) CurrentPosition() (float64, error) { - pos := 100.0 * float64(p.seeker.Position()) / float64(p.seeker.Len()) - return pos, nil +func (p *Player) CurrentPosition() (int, error) { + pos := math.Round(100.0 * float64(p.seeker.Position()) / float64(p.seeker.Len())) + return int(pos), nil } // TODO: double check best type for percentage parameter diff --git a/frontend/package.json b/frontend/package.json index 617c590..0c3aa62 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,6 +5,8 @@ "preview": "vite preview" }, "dependencies": { + "@lit-labs/signals": "^0.1.2", + "@shoelace-style/shoelace": "^2.20.1", "lit": "^3.2.1" }, "devDependencies": { diff --git a/frontend/package.json.md5 b/frontend/package.json.md5 index ff4b82a..edbaca1 100755 --- a/frontend/package.json.md5 +++ b/frontend/package.json.md5 @@ -1 +1 @@ -ca82a2e81936c5ea9427701a4c3665d9 \ No newline at end of file +fe84e1d3c95156e7d4a63999d84646b1 \ No newline at end of file diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index a50355a..ffa6d10 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@lit-labs/signals': + specifier: ^0.1.2 + version: 0.1.2 + '@shoelace-style/shoelace': + specifier: ^2.20.1 + version: 2.20.1(@floating-ui/utils@0.2.9)(@types/react@19.1.0) lit: specifier: ^3.2.1 version: 3.2.1 @@ -31,6 +37,10 @@ packages: resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} + '@ctrl/tinycolor@4.1.0': + resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} + engines: {node: '>=14'} + '@emmetio/extract-abbreviation@0.1.6': resolution: {integrity: sha512-Ce3xE2JvTSEbASFbRbA1gAIcMcZWdS2yUYRaQbeM0nbOzaZrUYfa3ePtcriYRZOZmr+CkKA+zbjhvTpIOAYVcw==} @@ -184,9 +194,26 @@ packages: cpu: [x64] os: [win32] + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@lit-labs/signals@0.1.2': + resolution: {integrity: sha512-hkOL0ua4ILeHlaJ8IqFKS+Y+dpYznWaDhdikzwt3zJ1/LPz3Etft4OPIMoltzbBJS5pyXPRseD/uWRlET3ImEA==} + '@lit-labs/ssr-dom-shim@1.3.0': resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==} + '@lit/react@1.0.7': + resolution: {integrity: sha512-cencnwwLXQKiKxjfFzSgZRngcWJzUDZi/04E0fSaF86wZgchMdvTyu+lE36DrUfvuus3bH8+xLPrhM1cTjwpzw==} + peerDependencies: + '@types/react': 17 || 18 || 19 + '@lit/reactive-element@2.0.4': resolution: {integrity: sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==} @@ -302,9 +329,22 @@ packages: cpu: [x64] os: [win32] + '@shoelace-style/animations@1.2.0': + resolution: {integrity: sha512-avvo1xxkLbv2dgtabdewBbqcJfV0e0zCwFqkPMnHFGbJbBHorRFfMAHh1NG9ymmXn0jW95ibUVH03E1NYXD6Gw==} + + '@shoelace-style/localize@3.2.1': + resolution: {integrity: sha512-r4C9C/5kSfMBIr0D9imvpRdCNXtUNgyYThc4YlS6K5Hchv1UyxNQ9mxwj+BTRH2i1Neits260sR3OjKMnplsFA==} + + '@shoelace-style/shoelace@2.20.1': + resolution: {integrity: sha512-FSghU95jZPGbwr/mybVvk66qRZYpx5FkXL+vLNpy1Vp8UsdwSxXjIHE3fsvMbKWTKi9UFfewHTkc5e7jAqRYoQ==} + engines: {node: '>=14.17.0'} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/react@19.1.0': + resolution: {integrity: sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -348,6 +388,14 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + composed-offset-position@0.0.6: + resolution: {integrity: sha512-Q7dLompI6lUwd7LWyIcP66r4WcS9u7AL2h8HaeipiRfCRPLMWqRx8fYsjb4OHi6UQFifO7XtNC2IlEJ1ozIFxw==} + peerDependencies: + '@floating-ui/utils': ^0.2.5 + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -477,6 +525,9 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} + qr-creator@1.0.0: + resolution: {integrity: sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -499,6 +550,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + signal-polyfill@0.2.2: + resolution: {integrity: sha512-p63Y4Er5/eMQ9RHg0M0Y64NlsQKpiu6MDdhBXpyywRuWiPywhJTpKJ1iB5K2hJEbFZ0BnDS7ZkJ+0AfTuL37Rg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -658,6 +712,8 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@ctrl/tinycolor@4.1.0': {} + '@emmetio/extract-abbreviation@0.1.6': {} '@esbuild/aix-ppc64@0.25.1': @@ -735,8 +791,28 @@ snapshots: '@esbuild/win32-x64@0.25.1': optional: true + '@floating-ui/core@1.6.9': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.6.13': + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/utils@0.2.9': {} + + '@lit-labs/signals@0.1.2': + dependencies: + lit: 3.2.1 + signal-polyfill: 0.2.2 + '@lit-labs/ssr-dom-shim@1.3.0': {} + '@lit/react@1.0.7(@types/react@19.1.0)': + dependencies: + '@types/react': 19.1.0 + '@lit/reactive-element@2.0.4': dependencies: '@lit-labs/ssr-dom-shim': 1.3.0 @@ -813,8 +889,30 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.37.0': optional: true + '@shoelace-style/animations@1.2.0': {} + + '@shoelace-style/localize@3.2.1': {} + + '@shoelace-style/shoelace@2.20.1(@floating-ui/utils@0.2.9)(@types/react@19.1.0)': + dependencies: + '@ctrl/tinycolor': 4.1.0 + '@floating-ui/dom': 1.6.13 + '@lit/react': 1.0.7(@types/react@19.1.0) + '@shoelace-style/animations': 1.2.0 + '@shoelace-style/localize': 3.2.1 + composed-offset-position: 0.0.6(@floating-ui/utils@0.2.9) + lit: 3.2.1 + qr-creator: 1.0.0 + transitivePeerDependencies: + - '@floating-ui/utils' + - '@types/react' + '@types/estree@1.0.6': {} + '@types/react@19.1.0': + dependencies: + csstype: 3.1.3 + '@types/trusted-types@2.0.7': {} '@vscode/web-custom-data@0.4.13': {} @@ -857,6 +955,12 @@ snapshots: color-name@1.1.4: {} + composed-offset-position@0.0.6(@floating-ui/utils@0.2.9): + dependencies: + '@floating-ui/utils': 0.2.9 + + csstype@3.1.3: {} + debug@4.4.0: dependencies: ms: 2.1.3 @@ -997,6 +1101,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + qr-creator@1.0.0: {} + queue-microtask@1.2.3: {} regenerator-runtime@0.14.1: {} @@ -1035,6 +1141,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + signal-polyfill@0.2.2: {} + source-map-js@1.2.1: {} string-width@4.2.3: diff --git a/frontend/src/components/audio-player/seekbar/seek-bar.ts b/frontend/src/components/audio-player/seekbar/seek-bar.ts index 53b9112..1db3a7b 100644 --- a/frontend/src/components/audio-player/seekbar/seek-bar.ts +++ b/frontend/src/components/audio-player/seekbar/seek-bar.ts @@ -1,14 +1,74 @@ -import { LitElement, html } from 'lit'; -import { customElement } from 'lit/decorators.js'; +import { LitElement, html, css, type PropertyValues } from 'lit'; +import { customElement, property} from 'lit/decorators.js'; +import {SignalWatcher, watch, signal} from '@lit-labs/signals'; +import { ref, createRef } from 'lit/directives/ref.js'; +import { SlRange } from '@node_modules/@shoelace-style/shoelace/dist/shoelace'; -const seekBar = () => html` - -`; +const progress = signal(20); @customElement('seek-bar') -export class SeekBar extends LitElement { +export class SeekBar extends SignalWatcher(LitElement) { + @property() + trackLengthSeconds: number = 100; + @property() + isPlaying: boolean = true; + + timerID: number = -1; + private rangeRef = createRef(); + + constructor(){ + super(); + this.startProgress(); + } + static override styles = css` + sl-range::part(base) { + --track-color-active: yellow; + --track-color-inactive: white; + --track-height: 6px; + --track-width: 50% + } + `; override render() { - return seekBar(); + return html` + + `; + } + + init(trackLength: number){ + this.trackLengthSeconds = trackLength; + } + + getSeekBarUpdateIntervalMillis(){ + return this.trackLengthSeconds * 10; + } + + // update progress update interval timer thing + // protected override update(changedProperties: PropertyValues): void { + // if (changedProperties.has("trackLengthSeconds")){ + // this.stopProgress(); + // this.startProgress(); + // } + // if(changedProperties.has("isPlaying")){ + // if(this.isPlaying){ + // this.startProgress(); + // } + // else{ + // this.stopProgress(); + // } + // } + // } + + stopProgress(){ + clearInterval(this.timerID); + } + + startProgress(){ + this.timerID = setInterval(this.incrementProgressValue, this.getSeekBarUpdateIntervalMillis()); + } + + async incrementProgressValue(){ + progress.set(progress.get() + 1); } } + diff --git a/frontend/wailsjs/go/player/Player.d.ts b/frontend/wailsjs/go/player/Player.d.ts index 61e1358..5ef53d3 100755 --- a/frontend/wailsjs/go/player/Player.d.ts +++ b/frontend/wailsjs/go/player/Player.d.ts @@ -5,6 +5,8 @@ import {player} from '../models'; export function ChangeVolume(arg1:number):Promise; +export function CurrentPosition():Promise; + export function Init(arg1:context.Context):Promise; export function LoadFile(arg1:string):Promise; @@ -17,4 +19,8 @@ export function Play():Promise; export function Resume():Promise; +export function Seek(arg1:number):Promise; + export function SetVolume(arg1:player.UserVolume):Promise; + +export function TrackLengthInSeconds():Promise; diff --git a/frontend/wailsjs/go/player/Player.js b/frontend/wailsjs/go/player/Player.js index ffc039f..30d250d 100755 --- a/frontend/wailsjs/go/player/Player.js +++ b/frontend/wailsjs/go/player/Player.js @@ -6,6 +6,10 @@ export function ChangeVolume(arg1) { return window['go']['player']['Player']['ChangeVolume'](arg1); } +export function CurrentPosition() { + return window['go']['player']['Player']['CurrentPosition'](); +} + export function Init(arg1) { return window['go']['player']['Player']['Init'](arg1); } @@ -30,6 +34,14 @@ export function Resume() { return window['go']['player']['Player']['Resume'](); } +export function Seek(arg1) { + return window['go']['player']['Player']['Seek'](arg1); +} + export function SetVolume(arg1) { return window['go']['player']['Player']['SetVolume'](arg1); } + +export function TrackLengthInSeconds() { + return window['go']['player']['Player']['TrackLengthInSeconds'](); +}