Skip to content

Commit

Permalink
feat: fetch instances after starting tui
Browse files Browse the repository at this point in the history
  • Loading branch information
sarowish committed Dec 1, 2022
1 parent f7d4561 commit b6236d0
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 32 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Fetch instances from api.invidious.io after starting the tui.

### Changed
- Change `modify channels` help text to `pick channels`

Expand Down
65 changes: 47 additions & 18 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ pub struct App {
new_video_ids: HashSet<String>,
channels_with_new_videos: HashSet<String>,
search: Search,
instance: Instance,
pub invidious_instances: Option<Vec<String>>,
instance: Option<Instance>,
pub hide_watched: bool,
io_tx: Sender<IoEvent>,
pub channel_selection: SelectionList<Channel>,
Expand All @@ -64,7 +65,8 @@ impl App {
prev_input_mode: InputMode::Normal,
cursor_position: 0,
search: Default::default(),
instance: Instance::new()?,
invidious_instances: crate::utils::read_instances().ok(),
instance: None,
new_video_ids: Default::default(),
channels_with_new_videos: Default::default(),
hide_watched: OPTIONS.hide_watched,
Expand All @@ -88,6 +90,11 @@ impl App {
app.set_mode_subs();
app.load_channels();
app.on_change_channel();
if app.invidious_instances.is_none() {
app.dispatch(IoEvent::FetchInstances);
} else {
app.set_instance()?;
}

app.tags = SelectionList::new(database::get_tags(&app.conn)?);

Expand Down Expand Up @@ -222,8 +229,8 @@ impl App {
}
}

pub fn instance(&self) -> Instance {
self.instance.clone()
pub fn instance(&self) -> Option<Instance> {
self.instance.as_ref().cloned()
}

fn find_channel_by_name(&mut self, channel_name: &str) -> Option<usize> {
Expand Down Expand Up @@ -357,19 +364,22 @@ impl App {
}

pub fn open_in_browser(&mut self) {
let Some(instance) = &self.instance else {
self.set_error_message("No Invidious instances available.");
return;
};

let url = match self.selected {
Selected::Channels => match self.get_current_channel() {
Some(current_channel) => format!(
"{}/channel/{}",
self.instance.domain, current_channel.channel_id
),
Some(current_channel) => {
format!("{}/channel/{}", instance.domain, current_channel.channel_id)
}
None => return,
},
Selected::Videos => match self.get_current_video() {
Some(current_video) => format!(
"{}/watch?v={}",
self.instance.domain, current_video.video_id
),
Some(current_video) => {
format!("{}/watch?v={}", instance.domain, current_video.video_id)
}
None => return,
},
};
Expand Down Expand Up @@ -915,31 +925,50 @@ impl App {
}

pub fn subscribe_to_channel(&mut self, channel_id: String) {
self.dispatch(IoEvent::SubscribeToChannel(channel_id));
if self.instance.is_some() {
self.dispatch(IoEvent::SubscribeToChannel(channel_id));
} else {
self.set_error_message("No Invidious instances available.");
}
}

pub fn subscribe_to_channels(&mut self) {
self.dispatch(IoEvent::SubscribeToChannels);
if self.instance.is_some() {
self.dispatch(IoEvent::SubscribeToChannels);
} else {
self.set_error_message("No Invidious instances available.");
}
}

pub fn refresh_channel(&mut self) {
if self.instance.is_none() {
self.set_error_message("No Invidious instances available.");
return;
}

if let Some(current_channel) = self.get_current_channel() {
let channel_id = current_channel.channel_id.clone();
self.dispatch(IoEvent::RefreshChannel(channel_id));
}
}

pub fn refresh_channels(&mut self) {
self.dispatch(IoEvent::RefreshChannels(false));
if self.instance.is_some() {
self.dispatch(IoEvent::RefreshChannels(false));
} else {
self.set_error_message("No Invidious instances available.");
}
}

pub fn change_instance(&mut self) -> Result<()> {
self.instance = Instance::new()?;
pub fn set_instance(&mut self) -> Result<()> {
if let Some(invidious_instances) = &self.invidious_instances {
self.instance = Some(Instance::new(invidious_instances)?);
}
Ok(())
}

pub fn refresh_failed_channels(&mut self) {
if let Err(e) = self.change_instance() {
if let Err(e) = self.set_instance() {
self.set_error_message(&format!("Couldn't change instance: {}", e));
return;
}
Expand Down
10 changes: 1 addition & 9 deletions src/invidious.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::channel::Video;
use crate::utils;
use crate::OPTIONS;
use anyhow::Context;
use anyhow::Result;
use rand::prelude::*;
use rand::thread_rng;
Expand Down Expand Up @@ -47,13 +45,7 @@ pub struct Instance {
}

impl Instance {
pub fn new() -> Result<Self> {
let invidious_instances = match utils::read_instances() {
Ok(instances) => instances,
Err(_) => {
utils::fetch_invidious_instances().with_context(|| "No instances available")?
}
};
pub fn new(invidious_instances: &[String]) -> Result<Self> {
let mut rng = thread_rng();
let domain = invidious_instances[rng.gen_range(0..invidious_instances.len())].to_string();
let agent = AgentBuilder::new()
Expand Down
27 changes: 22 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ pub enum IoEvent {
SubscribeToChannels,
RefreshChannel(String),
RefreshChannels(bool),
FetchInstances,
ClearMessage(u64),
}

Expand All @@ -193,6 +194,22 @@ async fn async_io_loop(
IoEvent::RefreshChannels(refresh_failed) => {
refresh_channels(&app, refresh_failed).await?
}
IoEvent::FetchInstances => {
app.lock().unwrap().set_message("Fetching instances");

match utils::fetch_invidious_instances() {
Ok(instances) => {
app.lock().unwrap().invidious_instances = Some(instances);
app.lock().unwrap().message.clear_message();
app.lock().unwrap().set_instance()?;
}
Err(e) => {
app.lock()
.unwrap()
.set_error_message(&format!("Couldn't fetch instances: {}", e));
}
}
}
IoEvent::ClearMessage(duration_seconds) => clear_message(&app, duration_seconds).await,
}
}
Expand Down Expand Up @@ -226,7 +243,7 @@ async fn subscribe_to_channel(app: &Arc<Mutex<App>>, channel_id: String) {
return;
}

let instance = app.lock().unwrap().instance();
let instance = app.lock().unwrap().instance().unwrap();
app.lock().unwrap().set_message("Subscribing to channel");
let app = app.clone();
tokio::task::spawn(async move {
Expand Down Expand Up @@ -262,7 +279,7 @@ async fn subscribe_to_channels(app: &Arc<Mutex<App>>) -> Result<()> {
count.lock().unwrap(),
total
));
let instance = app.lock().unwrap().instance();
let instance = app.lock().unwrap().instance().unwrap();
let streams = futures_util::stream::iter(channel_ids).map(|channel_id| {
let instance = instance.clone();
app.lock()
Expand Down Expand Up @@ -333,7 +350,7 @@ async fn subscribe_to_channels(app: &Arc<Mutex<App>>) -> Result<()> {
app.import_state.state.select(Some(0));
}

if let Err(e) = app.change_instance() {
if let Err(e) = app.set_instance() {
app.set_error_message(&format!("Couldn't change instance: {}", e));
}

Expand All @@ -346,7 +363,7 @@ async fn subscribe_to_channels(app: &Arc<Mutex<App>>) -> Result<()> {
}
async fn refresh_channel(app: &Arc<Mutex<App>>, channel_id: String) {
let now = std::time::Instant::now();
let instance = app.lock().unwrap().instance();
let instance = app.lock().unwrap().instance().unwrap();
app.lock()
.unwrap()
.set_channel_refresh_state(&channel_id, RefreshState::Refreshing);
Expand Down Expand Up @@ -410,7 +427,7 @@ async fn refresh_channels(app: &Arc<Mutex<App>>, refresh_failed: bool) -> Result
count.lock().unwrap(),
total
));
let instance = app.lock().unwrap().instance();
let instance = app.lock().unwrap().instance().unwrap();
let streams = futures_util::stream::iter(channel_ids).map(|channel_id| {
let instance = instance.clone();
app.lock()
Expand Down

0 comments on commit b6236d0

Please sign in to comment.