Skip to content

Commit 7823a85

Browse files
VimDiezelaome510
authored andcommitted
feat: make playback metadata fields configurable (#756)
- Add `playback_metadata_fields` option to config, allowing users to control which metadata fields (repeat, shuffle, volume, device) are shown in the playback UI. - Update example config and documentation to reflect the new option. - Users can now specify any combination and order of metadata fields to display in the `{metadata}` section.
1 parent e153b15 commit 7823a85

4 files changed

Lines changed: 70 additions & 51 deletions

File tree

docs/config.md

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,40 @@ All configuration files should be placed inside the application's configuration
2323

2424
`spotify_player` uses `app.toml` to configure general application configurations:
2525

26-
| Option | Description | Default |
27-
| --------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
28-
| `client_id` | the Spotify client's ID | `65b708073fc0480ea92a077233ca87bd` |
29-
| `client_id_command` | a shell command that prints the Spotify client ID to stdout (overrides `client_id`) | `None` |
30-
| `login_redirect_uri` | the redirect URI for authenticating the application | `http://127.0.0.1:8989/login` |
31-
| `client_port` | the port that the application's client is running on to handle CLI commands | `8080` |
32-
| `tracks_playback_limit` | the limit for the number of tracks played in a **tracks** playback | `50` |
33-
| `playback_format` | the format of the text in the playback's window | `{status} {track} • {artists} {liked}\n{album}\n{metadata}` |
34-
| `notify_format` | the format of a notification (`notify` feature only) | `{ summary = "{track} • {artists}", body = "{album}" }` |
35-
| `notify_timeout_in_secs` | the timeout (in seconds) of a notification (`notify` feature only) | `0` (no timeout) |
36-
| `player_event_hook_command` | the hook command executed when there is a new player event | `None` |
37-
| `ap_port` | the application's Spotify session connection port | `None` |
38-
| `proxy` | the application's Spotify session connection proxy | `None` |
39-
| `theme` | the application's theme | `default` |
40-
| `app_refresh_duration_in_ms` | the duration (in ms) between two consecutive application refreshes | `32` |
41-
| `playback_refresh_duration_in_ms` | the duration (in ms) between two consecutive playback refreshes | `0` |
42-
| `page_size_in_rows` | a page's size expressed as a number of rows (for page-navigation commands) | `20` |
43-
| `enable_media_control` | enable application media control support (`media-control` feature only) | `true` (Linux), `false` (Windows and MacOS) |
44-
| `enable_streaming` | enable streaming (`streaming` feature only) | `Always` |
45-
| `enable_notify` | enable notification (`notify` feature only) | `true` |
46-
| `enable_cover_image_cache` | store album's cover images in the cache folder | `true` |
47-
| `notify_streaming_only` | only send notification when streaming is enabled (`streaming` and `notify` feature only) | `false` |
48-
| `default_device` | the default device to connect to on startup if no playing device found | `spotify-player` |
49-
| `play_icon` | the icon to indicate playing state of a Spotify item | `` |
50-
| `pause_icon` | the icon to indicate pause state of a Spotify item | `▌▌` |
51-
| `liked_icon` | the icon to indicate the liked state of a song | `` |
52-
| `border_type` | the type of the application's borders | `Plain` |
53-
| `progress_bar_type` | the type of the playback progress bar | `Rectangle` |
54-
| `cover_img_width` | the width of the cover image (`image` feature only) | `5` |
55-
| `cover_img_length` | the length of the cover image (`image` feature only) | `9` |
56-
| `cover_img_scale` | the scale of the cover image (`image` feature only) | `1.0` |
57-
| `seek_duration_secs` | the duration (in seconds) to seek when using `SeekForward` and `SeekBackward` commands | `5` |
58-
| `sort_artist_albums_by_type` | sort albums on artist's pages by type, i.e. album or single | `false` |
26+
| Option | Description | Default |
27+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- |
28+
| `client_id` | the Spotify client's ID | `65b708073fc0480ea92a077233ca87bd` |
29+
| `client_id_command` | a shell command that prints the Spotify client ID to stdout (overrides `client_id`) | `None` |
30+
| `login_redirect_uri` | the redirect URI for authenticating the application | `http://127.0.0.1:8989/login` |
31+
| `client_port` | the port that the application's client is running on to handle CLI commands | `8080` |
32+
| `tracks_playback_limit` | the limit for the number of tracks played in a **tracks** playback | `50` |
33+
| `playback_format` | the format of the text in the playback's window | `{status} {track} • {artists} {liked}\n{album}\n{metadata}` |
34+
| `playback_metadata_fields` | list of ordered metadata fields to display in the playback UI's `{metadata}` section. Possible values: `"repeat"`, `"shuffle"`, `"volume"`, `"device"` | `["repeat", "shuffle", "volume", "device"]` |
35+
| `notify_format` | the format of a notification (`notify` feature only) | `{ summary = "{track} • {artists}", body = "{album}" }` |
36+
| `notify_timeout_in_secs` | the timeout (in seconds) of a notification (`notify` feature only) | `0` (no timeout) |
37+
| `player_event_hook_command` | the hook command executed when there is a new player event | `None` |
38+
| `ap_port` | the application's Spotify session connection port | `None` |
39+
| `proxy` | the application's Spotify session connection proxy | `None` |
40+
| `theme` | the application's theme | `default` |
41+
| `app_refresh_duration_in_ms` | the duration (in ms) between two consecutive application refreshes | `32` |
42+
| `playback_refresh_duration_in_ms` | the duration (in ms) between two consecutive playback refreshes | `0` |
43+
| `page_size_in_rows` | a page's size expressed as a number of rows (for page-navigation commands) | `20` |
44+
| `enable_media_control` | enable application media control support (`media-control` feature only) | `true` (Linux), `false` (Windows and MacOS) |
45+
| `enable_streaming` | enable streaming (`streaming` feature only) | `Always` |
46+
| `enable_notify` | enable notification (`notify` feature only) | `true` |
47+
| `enable_cover_image_cache` | store album's cover images in the cache folder | `true` |
48+
| `notify_streaming_only` | only send notification when streaming is enabled (`streaming` and `notify` feature only) | `false` |
49+
| `default_device` | the default device to connect to on startup if no playing device found | `spotify-player` |
50+
| `play_icon` | the icon to indicate playing state of a Spotify item | `` |
51+
| `pause_icon` | the icon to indicate pause state of a Spotify item | `▌▌` |
52+
| `liked_icon` | the icon to indicate the liked state of a song | `` |
53+
| `border_type` | the type of the application's borders | `Plain` |
54+
| `progress_bar_type` | the type of the playback progress bar | `Rectangle` |
55+
| `cover_img_width` | the width of the cover image (`image` feature only) | `5` |
56+
| `cover_img_length` | the length of the cover image (`image` feature only) | `9` |
57+
| `cover_img_scale` | the scale of the cover image (`image` feature only) | `1.0` |
58+
| `seek_duration_secs` | the duration (in seconds) to seek when using `SeekForward` and `SeekBackward` commands | `5` |
59+
| `sort_artist_albums_by_type` | sort albums on artist's pages by type, i.e. album or single | `false` |
5960

6061
### Notes
6162

examples/app.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ login_redirect_uri = "http://127.0.0.1:8989/login"
44
client_port = 8080
55
tracks_playback_limit = 50
66
playback_format = "{status} {track} • {artists}\n{album}\n{metadata}"
7+
playback_metadata_fields = ["repeat", "shuffle", "volume", "device"]
78
notify_format = { summary = "{track} • {artists}", body = "{album}" }
89
notify_timeout_in_secs = 0
910
app_refresh_duration_in_ms = 32

spotify_player/src/config/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub struct AppConfig {
6060
pub player_event_hook_command: Option<Command>,
6161

6262
pub playback_format: String,
63+
pub playback_metadata_fields: Vec<String>,
6364
#[cfg(feature = "notify")]
6465
pub notify_format: NotifyFormat,
6566
#[cfg(feature = "notify")]
@@ -268,6 +269,12 @@ impl Default for AppConfig {
268269
playback_format: String::from(
269270
"{status} {track} • {artists} {liked}\n{album}\n{metadata}",
270271
),
272+
playback_metadata_fields: vec![
273+
"repeat".to_string(),
274+
"shuffle".to_string(),
275+
"volume".to_string(),
276+
"device".to_string(),
277+
],
271278
#[cfg(feature = "notify")]
272279
notify_format: NotifyFormat {
273280
summary: String::from("{track} • {artists}"),

spotify_player/src/ui/playback.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -279,24 +279,34 @@ fn construct_playback_text(
279279
(episode.show.name.clone(), ui.theme.playback_album())
280280
}
281281
},
282-
"{metadata}" => (
283-
format!(
284-
"repeat: {} | shuffle: {} | volume: {} | device: {}",
285-
if playback.fake_track_repeat_state {
286-
"track (fake)"
287-
} else {
288-
<&'static str>::from(playback.repeat_state)
289-
},
290-
playback.shuffle_state,
291-
if let Some(volume) = playback.mute_state {
292-
format!("{volume}% (muted)")
293-
} else {
294-
format!("{}%", playback.volume.unwrap_or_default())
295-
},
296-
playback.device_name,
297-
),
298-
ui.theme.playback_metadata(),
299-
),
282+
"{metadata}" => {
283+
let repeat_value = if playback.fake_track_repeat_state {
284+
"track (fake)".to_string()
285+
} else {
286+
<&'static str>::from(playback.repeat_state).to_string()
287+
};
288+
289+
let volume_value = if let Some(volume) = playback.mute_state {
290+
format!("{volume}% (muted)")
291+
} else {
292+
format!("{}%", playback.volume.unwrap_or_default())
293+
};
294+
295+
let mut parts = vec![];
296+
297+
for field in &configs.app_config.playback_metadata_fields {
298+
match field.as_str() {
299+
"repeat" => parts.push(format!("repeat: {repeat_value}")),
300+
"shuffle" => parts.push(format!("shuffle: {}", playback.shuffle_state)),
301+
"volume" => parts.push(format!("volume: {volume_value}")),
302+
"device" => parts.push(format!("device: {}", playback.device_name)),
303+
_ => {}
304+
}
305+
}
306+
307+
let metadata_str = parts.join(" | ");
308+
(metadata_str, ui.theme.playback_metadata())
309+
}
300310
_ => continue,
301311
};
302312

0 commit comments

Comments
 (0)