Skip to content

Commit d61b80f

Browse files
authored
Loop to selection list when pressing q while playing (#23)
* Loop to selection list when pressing q while playing * Cache station list loaded from internet * Allow disabling the station cache with a flag * Fix typo in informational message
1 parent 801dc16 commit d61b80f

File tree

7 files changed

+167
-117
lines changed

7 files changed

+167
-117
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
authors = ["Marcos Gutiérrez Alonso <margual56@gmail.com>"]
33
description = "A simple radio cli for listening to your favourite streams from the console"
44
name = "radio-cli"
5-
version = "2.2.1"
5+
version = "2.3.0"
66
edition = "2021"
77
homepage = "https://github.com/margual56/radio-cli"
88
repository = "https://github.com/margual56/radio-cli"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The license is GPLv2
6868
Don't be surprised if these are not implemented in the end hehe (if there is no interest in the project, certainly not)
6969

7070
- [x] ~Audio (mpv) controls when not in verbose mode~
71-
- [ ] Loop to selection list when pressing `q` while playing
71+
- [x] Loop to selection list when pressing `q` while playing
7272
- [x] ~Some kind of online updating of the list of stations~ _(kind of)_
7373
- [x] ~Code optimizations/beautification~
7474
- [x] ~Search international online radios~

src/lib/browser.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use std::error::Error;
2+
use std::rc::Rc;
23

34
use crate::{station::Station, Config};
45
use inquire::{error::InquireError, Autocomplete, Text};
56
use radiobrowser::{blocking::RadioBrowserAPI, ApiCountry, ApiStation, StationOrder};
67

8+
pub type StationCache = Rc<Vec<ApiStation>>;
9+
710
#[derive(Debug, Clone)]
811
pub struct Stations {
9-
stations: Vec<ApiStation>,
12+
stations: StationCache,
1013
}
1114

1215
impl Autocomplete for Stations {
@@ -39,39 +42,47 @@ impl Autocomplete for Stations {
3942

4043
pub struct Browser {
4144
api: RadioBrowserAPI,
42-
config: Config,
43-
stations: Vec<ApiStation>,
45+
config: Rc<Config>,
46+
stations: StationCache,
4447
}
4548

4649
impl Browser {
47-
pub fn new(config: Config) -> Result<Browser, Box<dyn Error>> {
50+
pub fn new(
51+
config: Rc<Config>,
52+
cached_stations: Option<StationCache>,
53+
) -> Result<(Browser, StationCache), Box<dyn Error>> {
4854
let api = match RadioBrowserAPI::new() {
4955
Ok(r) => r,
5056
Err(e) => return Err(e),
5157
};
5258

53-
let stations = if let Some(code) = &config.country_code {
54-
match api
55-
.get_stations()
56-
.countrycode(code)
57-
.order(StationOrder::Clickcount)
58-
.send()
59-
{
60-
Ok(s) => s,
61-
Err(_e) => Vec::new(),
62-
}
63-
} else {
64-
match api.get_stations().order(StationOrder::Clickcount).send() {
65-
Ok(s) => s,
66-
Err(_e) => Vec::new(),
67-
}
68-
};
59+
let stations = cached_stations.unwrap_or_else(|| {
60+
Rc::new(if let Some(code) = &config.country_code {
61+
match api
62+
.get_stations()
63+
.countrycode(code)
64+
.order(StationOrder::Clickcount)
65+
.send()
66+
{
67+
Ok(s) => s,
68+
Err(_e) => Vec::new(),
69+
}
70+
} else {
71+
match api.get_stations().order(StationOrder::Clickcount).send() {
72+
Ok(s) => s,
73+
Err(_e) => Vec::new(),
74+
}
75+
})
76+
});
6977

70-
Ok(Browser {
71-
api,
72-
config,
78+
Ok((
79+
Browser {
80+
api,
81+
config,
82+
stations: stations.clone(),
83+
},
7384
stations,
74-
})
85+
))
7586
}
7687

7788
pub fn get_countries() -> Result<Vec<ApiCountry>, Box<dyn Error>> {

src/lib/cli_args.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ pub struct Cli {
5151
)]
5252
pub list_countries: bool,
5353

54+
/// Flag: --no-station-cache: Don't cache the station list loaded from the internet.
55+
#[clap(
56+
long = "no-station-cache",
57+
help = "Don't cache the station list loaded from the internet."
58+
)]
59+
pub no_station_cache: bool,
60+
5461
/// Show extra info
5562
#[clap(flatten)]
5663
pub verbose: clap_verbosity_flag::Verbosity,

src/lib/config.rs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ use crate::station::Station;
66
use crate::version::Version;
77

88
use colored::*;
9-
use inquire::{error::InquireError, Select};
109
use serde::de::{Deserializer, Error as SeError, Visitor};
1110
use serde::Deserialize;
1211
use std::fmt::{Formatter, Result as ResultFmt};
1312
use std::fs::File;
1413
use std::io::{Read, Write};
1514
use std::path::PathBuf;
1615

17-
use crate::browser::Browser;
18-
1916
const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli/main/config.json";
2017

2118
#[derive(Deserialize, Debug, Clone)]
@@ -134,7 +131,7 @@ impl Config {
134131
}
135132
}
136133

137-
pub fn get_url_for(self, station_name: &str) -> Option<String> {
134+
pub fn get_url_for(&self, station_name: &str) -> Option<String> {
138135
for s in self.data.iter() {
139136
if s.station.eq(station_name) {
140137
return Some(s.url.clone());
@@ -153,45 +150,6 @@ impl Config {
153150

154151
stations
155152
}
156-
157-
/// Prompts the user to select a station.
158-
/// Returns a station and if the station was taken from the internet.
159-
pub fn prompt(self) -> Result<(Station, bool), InquireError> {
160-
let max_lines: usize = match self.max_lines {
161-
Some(x) => x,
162-
None => Select::<Station>::DEFAULT_PAGE_SIZE,
163-
};
164-
165-
let res = Select::new(&"Select a station to play:".bold(), self.data.clone())
166-
.with_page_size(max_lines)
167-
.prompt();
168-
169-
let internet: bool;
170-
let station: Station = match res {
171-
Ok(s) => {
172-
if s.station.eq("Other") {
173-
internet = true;
174-
let result = Browser::new(self);
175-
176-
let brow = match result {
177-
Ok(b) => b,
178-
Err(_e) => return Err(InquireError::OperationInterrupted),
179-
};
180-
181-
match brow.prompt() {
182-
Ok(r) => r,
183-
Err(e) => return Err(e),
184-
}
185-
} else {
186-
internet = false;
187-
s
188-
}
189-
}
190-
Err(e) => return Err(e),
191-
};
192-
193-
Ok((station, internet))
194-
}
195153
}
196154

197155
fn deserialize_version<'de, D>(deserializer: D) -> Result<Version, D::Error>

0 commit comments

Comments
 (0)