feat: watch the selected anime in list
This commit is contained in:
parent
e0b8f758fd
commit
ceb8b29d9a
28
src/api.rs
28
src/api.rs
|
@ -1,12 +1,12 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct SearchResult {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub url: String,
|
||||
pub image: String,
|
||||
pub releaseDate: String,
|
||||
pub subOrDub: String,
|
||||
}
|
||||
|
@ -18,6 +18,19 @@ pub struct Search {
|
|||
pub results: Vec<SearchResult>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Quality {
|
||||
pub url: String,
|
||||
pub quality: String,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Watch {
|
||||
pub sources: Vec<Quality>,
|
||||
pub download: String,
|
||||
}
|
||||
|
||||
pub async fn query_anime(query: String) -> Result<Search, reqwest::Error> {
|
||||
reqwest::get(format!(
|
||||
"https://altoku-api.vercel.app/anime/gogoanime/{}?page=1",
|
||||
|
@ -28,3 +41,14 @@ pub async fn query_anime(query: String) -> Result<Search, reqwest::Error> {
|
|||
.json::<Search>()
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_url(id: String) -> Result<Watch, reqwest::Error> {
|
||||
reqwest::get(format!(
|
||||
"https://altoku-api.vercel.app/anime/gogoanime/watch/{}",
|
||||
id
|
||||
))
|
||||
.await
|
||||
.expect("Failed to get from API")
|
||||
.json::<Watch>()
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use crate::api::query_anime;
|
||||
use crate::api::{get_url, query_anime};
|
||||
use crate::app::{App, AppResult, ResultList};
|
||||
use crate::handler::KeyCode::*;
|
||||
|
||||
use crossterm::event::*;
|
||||
use tui_input::backend::crossterm::EventHandler;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
/// Handles the key events and updates the state of [`App`].
|
||||
pub async fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
|
||||
match key_event {
|
||||
|
@ -24,6 +26,7 @@ pub async fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<
|
|||
code: KeyCode::Enter,
|
||||
..
|
||||
} => {
|
||||
if app.editing {
|
||||
app.list = ResultList {
|
||||
state: app.list.state.clone(),
|
||||
items: query_anime(app.input.to_string()).await.unwrap().results,
|
||||
|
@ -33,19 +36,39 @@ pub async fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<
|
|||
app.editing = false;
|
||||
app.input.reset();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if app.editing == true {
|
||||
if app.editing {
|
||||
app.input.handle_event(&Event::Key(key_event));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
if app.editing != true {
|
||||
if !app.editing {
|
||||
match key_event.code {
|
||||
Char('j') | Down => app.list.next(),
|
||||
Char('k') | Up => app.list.previous(),
|
||||
Char('g') => app.go_top(),
|
||||
Char('G') => app.go_bottom(),
|
||||
KeyCode::Enter => {
|
||||
if let Some(i) = app.list.state.selected() {
|
||||
let mut url = String::new();
|
||||
for source in get_url(format!("{}-episode-1", app.list.items[i].id.clone()))
|
||||
.await
|
||||
.unwrap()
|
||||
.sources
|
||||
{
|
||||
if source.quality == "1080p" {
|
||||
url = source.url
|
||||
}
|
||||
}
|
||||
|
||||
let output = Command::new("mpv")
|
||||
.arg(format!("{}", url))
|
||||
.output()
|
||||
.expect("Failed to execute `mpv`");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
19
src/ui.rs
19
src/ui.rs
|
@ -1,9 +1,4 @@
|
|||
use ratatui::{
|
||||
prelude::*,
|
||||
style::Style,
|
||||
widgets::*,
|
||||
Frame,
|
||||
};
|
||||
use ratatui::{prelude::*, style::Style, widgets::*, Frame};
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
|
@ -58,12 +53,16 @@ pub fn render(app: &mut App, frame: &mut Frame) {
|
|||
}
|
||||
|
||||
let list = List::new(results)
|
||||
.block(Block::bordered().title("Search Results").style(match app.editing {
|
||||
.block(
|
||||
Block::bordered()
|
||||
.title("Search Results")
|
||||
.style(match app.editing {
|
||||
true => Style::default(),
|
||||
false => Style::default().yellow().bold(),
|
||||
}))
|
||||
.style(Style::default().white())
|
||||
.highlight_style(Style::default().add_modifier(Modifier::ITALIC))
|
||||
}),
|
||||
)
|
||||
.style(Style::default().white().not_bold())
|
||||
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
||||
.highlight_symbol("┃ ")
|
||||
.repeat_highlight_symbol(true)
|
||||
.direction(ListDirection::TopToBottom);
|
||||
|
|
Reference in a new issue