From 066e3817378563fb4901b9184f5dd241d0df9c5a Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Thu, 23 Apr 2026 21:38:46 +0200 Subject: [PATCH] Fix/beautify the account overview --- pkg/models/models.go | 1 + pkg/service/constants/constants.go | 16 ++++++++++++++++ pkg/service/handlers/handlers_account_mgmt.go | 1 + pkg/service/handlers/web/js/script.js | 17 ++++++++++------- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/pkg/models/models.go b/pkg/models/models.go index 371c08a..a6d89f1 100644 --- a/pkg/models/models.go +++ b/pkg/models/models.go @@ -755,6 +755,7 @@ type FullResponseSource struct { Username string `json:"username" xml:"username"` Account string `json:"account,omitempty" xml:"account,attr,omitempty"` SourceLabel string `json:"source_label" xml:"-"` + ProviderLabel string `json:"provider_label,omitempty" xml:"-"` } // FullResponsePreset represents a preset specifically for the /full response. diff --git a/pkg/service/constants/constants.go b/pkg/service/constants/constants.go index 2142d05..7bf1df4 100644 --- a/pkg/service/constants/constants.go +++ b/pkg/service/constants/constants.go @@ -265,6 +265,22 @@ func GetProviderName(providerID string) string { return providerID } +// GetProviderLabel returns the user-friendly label for a provider ID (e.g. "TuneIn Radio", "Spotify"). +func GetProviderLabel(providerID string) string { + id, err := strconv.Atoi(providerID) + if err != nil { + return "" + } + + for _, p := range StaticProviders { + if p.ID == id { + return p.Label + } + } + + return "" +} + // GetProviders returns a list of known source provider names. func GetProviders() []string { var providers []string diff --git a/pkg/service/handlers/handlers_account_mgmt.go b/pkg/service/handlers/handlers_account_mgmt.go index cff8884..8b4237e 100644 --- a/pkg/service/handlers/handlers_account_mgmt.go +++ b/pkg/service/handlers/handlers_account_mgmt.go @@ -269,6 +269,7 @@ func mapToFullResponseSource(src *models.ConfiguredSource) models.FullResponseSo UpdatedOn: src.UpdatedOn, Account: src.SourceKey.Account, SourceLabel: constants.GetSourceLabel(src.Type), + ProviderLabel: constants.GetProviderLabel(src.SourceProviderID), SourceSettings: src.SourceSettings, } fs.Credential.Value = src.Secret diff --git a/pkg/service/handlers/web/js/script.js b/pkg/service/handlers/web/js/script.js index 4dd84bd..5d76128 100644 --- a/pkg/service/handlers/web/js/script.js +++ b/pkg/service/handlers/web/js/script.js @@ -707,8 +707,8 @@ async function fetchAccountDetails(accountId) { itemName = p.name || (p.source ? (p.source.source_label || p.source.name || p.source.type) : "Unknown"); if (p.source) { const s = p.source; - const name = s.source_label || s.source_name || s.name || s.type; - const account = (s.account && s.account !== s.username) ? ` [${s.account}]` : ""; + const name = s.provider_label || s.display_name || s.source_name || s.name || s.type; + const account = (s.account && s.account !== s.username && s.account !== name) ? ` [${s.account}]` : ""; const finalName = name || s.type || "Unknown Source"; if (finalName) { sourceLabel = `
via ${finalName}${account}`; @@ -732,14 +732,17 @@ async function fetchAccountDetails(accountId) { let sourceLabel = ""; if (r.source) { const s = r.source; - const sName = s.source_label || s.source_name || s.name || s.type; - const account = (s.account && s.account !== s.username) ? ` [${s.account}]` : ""; + const sName = s.provider_label || s.display_name || s.source_name || s.name || s.type; + const account = (s.account && s.account !== s.username && s.account !== sName) ? ` [${s.account}]` : ""; const finalSName = sName || s.type || "Unknown Source"; if (finalSName) { sourceLabel = `
via ${finalSName}${account}`; } } - return `
  • ${name}${sourceLabel}
    ${r.created_on ? new Date(r.created_on * 1000).toLocaleString() : 'N/A'}
  • `; + const dateRaw = r.last_played_at || r.created_on; + const dateObj = dateRaw ? (isNaN(Number(dateRaw)) ? new Date(dateRaw) : new Date(Number(dateRaw) * 1000)) : null; + const dateStr = dateObj ? dateObj.toLocaleString('sv-SE') : 'N/A'; // sv-SE produces YYYY-MM-DD HH:MM:SS with 24h time + return `
  • ${name}${sourceLabel}
    ${dateStr}
  • `; }).join("") : "
  • No recents
  • "} @@ -750,9 +753,9 @@ async function fetchAccountDetails(accountId) {
    Configured Sources
    ${device.sources ? device.sources.filter(s => (s.source_label || s.source_name || s.name || s.type)).map(s => { - const sourceName = s.source_label || s.source_name || s.name || s.type; + const sourceName = s.provider_label || s.display_name || s.source_name || s.name || s.type; const usernameSuffix = (s.username && s.username !== "Local") ? ` (${s.username})` : ""; - const accountSuffix = (s.account && s.account !== s.username) ? ` [${s.account}]` : ""; + const accountSuffix = (s.account && s.account !== s.username && s.account !== sourceName) ? ` [${s.account}]` : ""; return ` ${sourceName}${usernameSuffix}${accountSuffix}