diff --git a/parenscript/player.lisp b/parenscript/player.lisp
index 6f98cc3..a72bd1e 100644
--- a/parenscript/player.lisp
+++ b/parenscript/player.lisp
@@ -93,15 +93,15 @@
;; Restore user quality preference
(let ((selector (ps:chain document (get-element-by-id "live-stream-quality")))
- (stream-quality (ps:chain (ps:@ local-storage (get-item "stream-quality")) "aac")))
- (when (and selector (not (== (ps:@ selector value) stream-quality)))
+ (stream-quality (or (ps:chain local-storage (get-item "stream-quality")) "aac")))
+ (when (and selector (not (= (ps:@ selector value) stream-quality)))
(setf (ps:@ selector value) stream-quality)
(ps:chain selector (dispatch-event (new "Event" "change"))))))))
;; Frame redirection logic
(defun redirect-when-frame ()
- (let ((path (ps:@ window location pathname))
- (is-frameset-page (not (== (ps:@ window parent) (ps:@ window self))))
+ (let* ((path (ps:@ window location pathname))
+ (is-frameset-page (not (= (ps:@ window parent) (ps:@ window self))))
(is-content-frame (ps:chain path (includes "player-content"))))
(when (and is-frameset-page (not is-content-frame))
@@ -133,13 +133,12 @@
(add-event-listener "input" update-volume))
;; Audio player events
- (when *audio-player*
- (ps:chain *audio-player*
- (add-event-listener "loadedmetadata" update-time-display)
- (add-event-listener "timeupdate" update-time-display)
- (add-event-listener "ended" handle-track-end)
- (add-event-listener "play" (lambda () (update-play-button "⏸️ Pause")))
- (add-event-listener "pause" (lambda () (update-play-button "▶️ Play")))))
+ (when (and *audio-player* (ps:chain *audio-player* add-event-listener))
+ (ps:chain *audio-player* (add-event-listener "loadedmetadata" update-time-display))
+ (ps:chain *audio-player* (add-event-listener "timeupdate" update-time-display))
+ (ps:chain *audio-player* (add-event-listener "ended" handle-track-end))
+ (ps:chain *audio-player* (add-event-listener "play" (lambda () (update-play-button "⏸️ Pause"))))
+ (ps:chain *audio-player* (add-event-listener "pause" (lambda () (update-play-button "▶️ Play")))))
;; Playlist controls
(ps:chain (ps:chain document (get-element-by-id "create-playlist"))
@@ -162,17 +161,17 @@
(then (lambda (result)
;; Handle RADIANCE API wrapper format
(let ((data (or (ps:@ result data) result)))
- (if (== (ps:@ data status) "success")
+ (if (= (ps:@ data status) "success")
(progn
(setf *tracks* (or (ps:@ data tracks) (array)))
(display-tracks *tracks*))
(progn
(ps:chain console (error "Error loading tracks:" (ps:@ data error)))
- (setf (ps:chain (ps:chain document (get-element-by-id "track-list")) inner-html)
+ (setf (ps:chain (ps:chain document (get-element-by-id "track-list")) inner-h-t-m-l)
"
"
"
"
"
" (or (ps:@ track title) "Unknown Title") "
"
@@ -216,7 +215,7 @@
"
"))))
(join ""))))
- (setf (ps:@ container inner-html) tracks-html)
+ (setf (ps:@ container inner-h-t-m-l) tracks-html)
;; Update pagination controls
(setf (ps:chain (ps:chain document (get-element-by-id "library-page-info")) text-content)
@@ -249,7 +248,7 @@
(defun change-library-tracks-per-page ()
(setf *library-tracks-per-page*
- (parseInt (ps:chain (ps:chain document (get-element-by-id "library-tracks-per-page")) value)))
+ (parse-int (ps:chain (ps:chain document (get-element-by-id "library-tracks-per-page")) value)))
(setf *library-current-page* 1)
(render-library-page))
@@ -312,13 +311,13 @@
;; Play from queue
(let ((next-track (ps:chain *play-queue* (shift))))
(play-track (ps:chain *tracks*
- (find-index (lambda (trk) (== (ps:@ trk id) (ps:@ next-track id))))))
+ (find-index (lambda (trk) (= (ps:@ trk id) (ps:@ next-track id))))))
(update-queue-display))
;; Play next track in library
(let ((next-index (if *is-shuffled*
(floor (* (random) (ps:@ *tracks* length)))
(mod (+ *current-track-index* 1) (ps:@ *tracks* length)))))
- (play-track next-index)))))
+ (play-track next-index))))
;; Handle track end
(defun handle-track-end ()
@@ -344,7 +343,7 @@
;; Update volume
(defun update-volume ()
- (let ((volume (/ (parseInt (ps:chain (ps:chain document (get-element-by-id "volume-slider")) value)) 100)))
+ (let ((volume (/ (parse-int (ps:chain (ps:chain document (get-element-by-id "volume-slider")) value)) 100)))
(when *audio-player*
(setf (ps:@ *audio-player* volume) volume))))
@@ -386,8 +385,8 @@
;; Update queue display
(defun update-queue-display ()
(let ((container (ps:chain document (get-element-by-id "play-queue"))))
- (if (== (ps:@ *play-queue* length) 0)
- (setf (ps:@ container inner-html) "
Queue is empty
")
+ (if (= (ps:@ *play-queue* length) 0)
+ (setf (ps:@ container inner-h-t-m-l) "
Queue is empty
")
(let ((queue-html (ps:chain *play-queue*
(map (lambda (track index)
(+ "
"
@@ -398,7 +397,7 @@
""
"
")))
(join ""))))
- (setf (ps:@ container inner-html) queue-html))))
+ (setf (ps:@ container inner-h-t-m-l) queue-html)))))
;; Remove track from queue
(defun remove-from-queue (index)
@@ -413,25 +412,25 @@
;; Create playlist
(defun create-playlist ()
(let ((name (ps:chain (ps:chain document (get-element-by-id "new-playlist-name")) value (trim))))
- (when (not (== name ""))
- (let ((form-data (new "FormData")))
+ (when (not (= name ""))
+ (let ((form-data (new -Form-data)))
(ps:chain form-data (append "name" name))
(ps:chain form-data (append "description" ""))
(ps:chain (fetch "/api/asteroid/playlists/create"
(ps:create :method "POST" :body form-data))
- (then (lambda (response) (ps:chain response (json))))
+ (then (lambda (response)
+ (ps:chain response (json))))
(then (lambda (result)
;; Handle RADIANCE API wrapper format
(let ((data (or (ps:@ result data) result)))
- (if (== (ps:@ data status) "success")
+ (if (= (ps:@ data status) "success")
(progn
(alert (+ "Playlist \"" name "\" created successfully!"))
(setf (ps:chain (ps:chain document (get-element-by-id "new-playlist-name")) value) "")
;; Wait a moment then reload playlists
- (ps:chain (new "Promise" (lambda (resolve) (setTimeout resolve 500)))
- (then (lambda () (load-playlists)))))
+ (set-timeout load-playlists 500))
(alert (+ "Error creating playlist: " (ps:@ data message)))))))
(catch (lambda (error)
(ps:chain console (error "Error creating playlist:" error))
@@ -453,54 +452,55 @@
(then (lambda (create-result)
;; Handle RADIANCE API wrapper format
(let ((create-data (or (ps:@ create-result data) create-result)))
- (if (== (ps:@ create-data status) "success")
+ (if (= (ps:@ create-data status) "success")
(progn
- ;; Wait a moment for database to update
- (ps:chain (new "Promise" (lambda (resolve) (setTimeout resolve 500)))
- (then (lambda ()
- ;; Get the new playlist ID by fetching playlists
- (ps:chain (fetch "/api/asteroid/playlists")
- (then (lambda (response) (ps:chain response (json))))
- (then (lambda (playlists-result)
- ;; Handle RADIANCE API wrapper format
- (let ((playlist-result-data (or (ps:@ playlists-result data) playlists-result)))
- (if (and (== (ps:@ playlist-result-data status) "success")
- (> (ps:@ playlist-result-data playlists length) 0))
- (progn
- ;; Find the playlist with matching name (most recent)
- (let ((new-playlist (or (ps:chain (ps:@ playlist-result-data playlists)
- (find (lambda (p) (== (ps:@ p name) name))))
- (aref (ps:@ playlist-result-data playlists)
- (- (ps:@ playlist-result-data playlists length) 1)))))
-
- ;; Add all tracks from queue to playlist
- (let ((added-count 0))
- (ps:chain *play-queue*
- (for-each (lambda (track)
- (let ((track-id (ps:@ track id)))
- (when track-id
- (let ((add-form-data (new "FormData")))
- (ps:chain add-form-data (append "playlist-id" (ps:@ new-playlist id)))
- (ps:chain add-form-data (append "track-id" track-id))
-
- (ps:chain (fetch "/api/asteroid/playlists/add-track"
- (ps:create :method "POST" :body add-form-data))
- (then (lambda (response) (ps:chain response (json))))
- (then (lambda (add-result)
- (when (== (ps:@ add-result data status) "success")
- (setf added-count (+ added-count 1)))))
- (catch (lambda (err)
- (ps:chain console (log "Error adding track:" err)))))))))))
-
- (alert (+ "Playlist \"" name "\" created with " added-count " tracks!"))
- (load-playlists))))
- (progn
- (alert (+ "Playlist created but could not add tracks. Error: "
- (or (ps:@ playlist-result-data message) "Unknown")))
- (load-playlists))))))
- (catch (lambda (error)
- (ps:chain console (error "Error fetching playlists:" error))
- (alert "Playlist created but could not add tracks"))))))))
+ ;; Wait a moment for database to update, then fetch playlists
+ (set-timeout
+ (lambda ()
+ ;; Get the new playlist ID by fetching playlists
+ (ps:chain (fetch "/api/asteroid/playlists")
+ (then (lambda (response) (ps:chain response (json))))
+ (then (lambda (playlists-result)
+ ;; Handle RADIANCE API wrapper format
+ (let ((playlist-result-data (or (ps:@ playlists-result data) playlists-result)))
+ (if (and (= (ps:@ playlist-result-data status) "success")
+ (> (ps:@ playlist-result-data playlists length) 0))
+ (progn
+ ;; Find the playlist with matching name (most recent)
+ (let ((new-playlist (or (ps:chain (ps:@ playlist-result-data playlists)
+ (find (lambda (p) (= (ps:@ p name) name))))
+ (aref (ps:@ playlist-result-data playlists)
+ (- (ps:@ playlist-result-data playlists length) 1)))))
+
+ ;; Add all tracks from queue to playlist
+ (let ((added-count 0))
+ (ps:chain *play-queue*
+ (for-each (lambda (track)
+ (let ((track-id (ps:@ track id)))
+ (when track-id
+ (let ((add-form-data (new -Form-data)))
+ (ps:chain add-form-data (append "playlist-id" (ps:@ new-playlist id)))
+ (ps:chain add-form-data (append "track-id" track-id))
+
+ (ps:chain (fetch "/api/asteroid/playlists/add-track"
+ (ps:create :method "POST" :body add-form-data))
+ (then (lambda (response) (ps:chain response (json))))
+ (then (lambda (add-result)
+ (when (= (ps:@ add-result data status) "success")
+ (setf added-count (+ added-count 1)))))
+ (catch (lambda (err)
+ (ps:chain console (log "Error adding track:" err)))))))))))
+
+ (alert (+ "Playlist \"" name "\" created with " added-count " tracks!"))
+ (load-playlists))))
+ (progn
+ (alert (+ "Playlist created but could not add tracks. Error: "
+ (or (ps:@ playlist-result-data message) "Unknown")))
+ (load-playlists))))))
+ (catch (lambda (error)
+ (ps:chain console (error "Error fetching playlists:" error))
+ (alert "Playlist created but could not add tracks")))))
+ 500))
(alert (+ "Error creating playlist: " (ps:@ create-data message)))))))
(catch (lambda (error)
(ps:chain console (error "Error saving queue as playlist:" error))
@@ -514,9 +514,9 @@
(then (lambda (response) (ps:chain response (json))))
(then (lambda (result)
(let ((playlists (cond
- ((and (ps:@ result data) (== (ps:@ result data status) "success"))
+ ((and (ps:@ result data) (= (ps:@ result data status) "success"))
(or (ps:@ result data playlists) (array)))
- ((== (ps:@ result status) "success")
+ ((= (ps:@ result status) "success")
(or (ps:@ result playlists) (array)))
(t
(array)))))
@@ -529,8 +529,8 @@
(defun display-playlists (playlists)
(let ((container (ps:chain document (get-element-by-id "playlists-container"))))
- (if (or (not playlists) (== (ps:@ playlists length) 0))
- (setf (ps:@ container inner-html) "
No playlists created yet.
")
+ (if (or (not playlists) (= (ps:@ playlists length) 0))
+ (setf (ps:@ container inner-h-t-m-l) "
No playlists created yet.
")
(let ((playlists-html (ps:chain playlists
(map (lambda (playlist)
(+ "
"
@@ -541,10 +541,10 @@
"
"
""
"
"
- "
"))
- (join "")))))
+ "
")))
+ (join ""))))
- (setf (ps:@ container inner-html) playlists-html)))))
+ (setf (ps:@ container inner-h-t-m-l) playlists-html)))))
;; Load playlist into queue
(defun load-playlist (playlist-id)
@@ -554,7 +554,7 @@
(then (lambda (result)
;; Handle RADIANCE API wrapper format
(let ((data (or (ps:@ result data) result)))
- (if (and (== (ps:@ data status) "success") (ps:@ data playlist))
+ (if (and (= (ps:@ data status) "success") (ps:@ data playlist))
(let ((playlist (ps:@ data playlist)))
;; Clear current queue
@@ -566,7 +566,7 @@
(for-each (lambda (track)
;; Find the full track object from our tracks array
(let ((full-track (ps:chain *tracks*
- (find (lambda (trk) (== (ps:@ trk id) (ps:@ track id)))))))
+ (find (lambda (trk) (= (ps:@ trk id) (ps:@ track id)))))))
(when full-track
(setf (aref *play-queue* (ps:@ *play-queue* length)) full-track)))))
@@ -577,11 +577,11 @@
(when (> (ps:@ *play-queue* length) 0)
(let ((first-track (ps:chain *play-queue* (shift)))
(track-index (ps:chain *tracks*
- (find-index (lambda (trk) (== (ps:@ trk id) (ps:@ first-track id))))))
+ (find-index (lambda (trk) (= (ps:@ trk id) (ps:@ first-track id))))))
)
(when (>= track-index 0)
(play-track track-index))))))
- (when (or (not (ps:@ playlist tracks)) (== (ps:@ playlist tracks length) 0))
+ (when (or (not (ps:@ playlist tracks)) (= (ps:@ playlist tracks length) 0))
(alert (+ "Playlist \"" (ps:@ playlist name) "\" is empty"))))
(alert (+ "Error loading playlist: " (or (ps:@ data message) "Unknown error")))))))
(catch (lambda (error)
@@ -631,23 +631,24 @@
;; Update now playing information
(defun update-now-playing ()
(ps:chain
- (ps:chain (fetch "/api/asteroid/partial/now-playing"))
+ (fetch "/api/asteroid/partial/now-playing")
(then (lambda (response)
- (let ((content-type (ps:chain response (headers) (get "content-type"))))
+ (let ((content-type (ps:chain response headers (get "content-type"))))
(if (ps:chain content-type (includes "text/html"))
(ps:chain response (text))
(progn
(ps:chain console (log "Error connecting to stream"))
"")))))
(then (lambda (data)
- (setf (ps:chain (ps:chain document (get-element-by-id "now-playing")) inner-html) data)))
+ (setf (ps:chain document (get-element-by-id "now-playing") inner-h-t-m-l) data)))
+
(catch (lambda (error)
(ps:chain console (log "Could not fetch stream status:" error))))))
;; Initial update after 1 second
- (ps:chain (setTimeout update-now-playing 1000))
+ (set-timeout update-now-playing 1000)
;; Update live stream info every 10 seconds
- (ps:chain (set-interval update-now-playing 10000))
+ (set-interval update-now-playing 10000)
;; Make functions globally accessible for onclick handlers
(defvar window (ps:@ window))
diff --git a/playlist-management.lisp b/playlist-management.lisp
index 8a40a58..b236157 100644
--- a/playlist-management.lisp
+++ b/playlist-management.lisp
@@ -14,10 +14,9 @@
(setf (dm:field playlist "user-id") user-id)
(setf (dm:field playlist "name") name)
(setf (dm:field playlist "description") (or description ""))
- (setf (dm:field playlist "track-ids") "") ; Empty string for text field
+ ;; Note: track-ids column removed - using playlist_tracks junction table instead
;; Let database default handle created-date (CURRENT_TIMESTAMP)
(format t "Creating playlist with user-id: ~a (type: ~a)~%" user-id (type-of user-id))
- (format t "Playlist data: ~a~%" (data-model-as-alist playlist))
(dm:insert playlist)
t))