diff --git a/parenscript/profile.lisp b/parenscript/profile.lisp index eb12b92..cbcc146 100644 --- a/parenscript/profile.lisp +++ b/parenscript/profile.lisp @@ -232,6 +232,54 @@ (defun load-more-favorites () (show-message "Loading more favorites..." "info")) + (defun load-activity-chart () + (ps:chain + (fetch "/api/asteroid/user/activity?days=30") + (then (lambda (response) (ps:chain response (json)))) + (then (lambda (result) + (let ((data (or (ps:@ result data) result)) + (container (ps:chain document (get-element-by-id "activity-chart"))) + (total-el (ps:chain document (get-element-by-id "activity-total")))) + (when container + (if (and (= (ps:@ data status) "success") + (ps:@ data activity) + (> (ps:@ data activity length) 0)) + (let ((activity (ps:@ data activity)) + (max-count 1) + (total 0)) + ;; Find max for scaling + (ps:chain activity (for-each (lambda (day) + (let ((count (or (ps:@ day track_count) 0))) + (setf total (+ total count)) + (when (> count max-count) + (setf max-count count)))))) + ;; Build chart HTML + (let ((html "
")) + (setf (ps:@ container inner-h-t-m-l) html)) + ;; Update total + (when total-el + (setf (ps:@ total-el text-content) (+ "Total: " total " tracks in the last 30 days")))) + ;; No data + (setf (ps:@ container inner-h-t-m-l) "No listening activity yet. Start listening to build your history!
")))))) + (catch (lambda (error) + (ps:chain console (error "Error loading activity:" error)) + (let ((container (ps:chain document (get-element-by-id "activity-chart")))) + (when container + (setf (ps:@ container inner-h-t-m-l) "Failed to load activity data
"))))))) + (defun load-profile-data () (ps:chain console (log "Loading profile data...")) @@ -254,7 +302,8 @@ (load-listening-stats) (load-recent-tracks) (load-favorites) - (load-top-artists)) + (load-top-artists) + (load-activity-chart)) ;; Action functions (defun load-more-recent-tracks () diff --git a/static/asteroid.css b/static/asteroid.css index cef3ae1..fcda789 100644 --- a/static/asteroid.css +++ b/static/asteroid.css @@ -1701,4 +1701,75 @@ body.popout-body .status-mini{ .favorites-list .btn-small{ padding: 4px 8px; font-size: 0.8em; +} + +.activity-chart{ + padding: 15px; +} + +.activity-chart .chart-container{ + min-height: 120px; + display: flex; + align-items: flex-end; + justify-content: center; +} + +.activity-chart .chart-bars{ + display: flex; + align-items: flex-end; + justify-content: center; + gap: 4px; + height: 100px; + width: 100%; + max-width: 600px; +} + +.activity-chart .chart-bar-wrapper{ + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + max-width: 20px; +} + +.activity-chart .chart-bar{ + width: 100%; + min-height: 2px; + background: linear-gradient(to top, #006600, #00cc00); + border-radius: 2px 2px 0 0; + -moz-transition: height 0.3s ease; + -o-transition: height 0.3s ease; + -webkit-transition: height 0.3s ease; + -ms-transition: height 0.3s ease; + transition: height 0.3s ease; +} + +.activity-chart .chart-bar:hover{ + background: linear-gradient(to top, #009900, #00ff00); +} + +.activity-chart .chart-day{ + font-size: 0.6em; + color: #666; + margin-top: 4px; +} + +.activity-chart .chart-note{ + text-align: center; + color: #888; + font-size: 0.9em; + margin-top: 10px; +} + +.activity-chart .loading-message{ + color: #666; + font-style: italic; + text-align: center; +} + +.activity-chart .no-data{ + color: #666; + font-style: italic; + text-align: center; + padding: 20px; } \ No newline at end of file diff --git a/static/asteroid.lass b/static/asteroid.lass index c811de7..6460b89 100644 --- a/static/asteroid.lass +++ b/static/asteroid.lass @@ -1359,4 +1359,62 @@ (.btn-small :padding "4px 8px" :font-size "0.8em")) + + ;; Activity chart styling + (.activity-chart + :padding "15px" + + (.chart-container + :min-height "120px" + :display "flex" + :align-items "flex-end" + :justify-content "center") + + (.chart-bars + :display "flex" + :align-items "flex-end" + :justify-content "center" + :gap "4px" + :height "100px" + :width "100%" + :max-width "600px") + + (.chart-bar-wrapper + :display "flex" + :flex-direction "column" + :align-items "center" + :flex "1" + :max-width "20px") + + (.chart-bar + :width "100%" + :min-height "2px" + :background "linear-gradient(to top, #006600, #00cc00)" + :border-radius "2px 2px 0 0" + :transition "height 0.3s ease") + + ((:and .chart-bar :hover) + :background "linear-gradient(to top, #009900, #00ff00)") + + (.chart-day + :font-size "0.6em" + :color "#666" + :margin-top "4px") + + (.chart-note + :text-align "center" + :color "#888" + :font-size "0.9em" + :margin-top "10px") + + (.loading-message + :color "#666" + :font-style "italic" + :text-align "center") + + (.no-data + :color "#666" + :font-style "italic" + :text-align "center" + :padding "20px")) ) ;; End of let block diff --git a/template/profile.ctml b/template/profile.ctml index 3a6635e..f829f43 100644 --- a/template/profile.ctml +++ b/template/profile.ctml @@ -146,18 +146,11 @@Activity over the last 30 days
-Tracks played over the last 30 days
+Listening hours per day
+Total: 0 tracks