use gloo_net::http::Request;
use itertools::Itertools;
use wasm_bindgen::*;
use web_sys::{EventTarget, HtmlInputElement};
use yew::prelude::*;
use lib::lib::*;
use yew_router::scope_ext::RouterScopeExt;
use crate::Route;
#[derive(Properties, Clone, PartialEq, Eq)]
pub struct ResultComponentProps {
result: IndexedResource,
}
#[function_component(ResultComponent)]
fn result_component(props: &ResultComponentProps) -> Html {
html! {
}
}
pub struct OSSE {
pub search_query: String,
pub results: Option>, //TODO: some loading?
}
#[derive(Properties, PartialEq, Eq)]
pub struct OSSEProps {
pub api_endpoint: String,
pub initial_search_query: Option,
}
pub enum OSSEMessage {
SearchSubmitted,
SearchChanged(String),
SearchFinished(Vec),
}
impl Component for OSSE {
type Message = OSSEMessage;
type Properties = OSSEProps;
//TODO: No code duplication for fetching in create() and update() - NEED TO URL ENCODE AND DECODE SEARCH QUERY
fn create(ctx: &Context) -> Self {
let mut search_query = String::from("");
//we push an update message if inital_search_query is not none
if let Some(initial_search_query) = ctx.props().initial_search_query.clone() {
search_query = initial_search_query.clone();
let api_endpoint = ctx.props().api_endpoint.clone();
ctx.link().send_future(async move {
let endpoint = format!("{}/search/{}", api_endpoint, initial_search_query);
let fetched_response = Request::get(endpoint.as_str()).send().await.unwrap();
let fetched_results: Vec = match fetched_response.json().await {
Err(e) => panic!("Im panic: {}", e),
Ok(json) => json,
};
OSSEMessage::SearchFinished(fetched_results)
});
}
OSSE {
search_query: urlencoding::decode(search_query.as_str()).to_owned().unwrap().to_string(),
results: None,
}
}
fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool {
match msg {
OSSEMessage::SearchSubmitted => {
let api_endpoint = ctx.props().api_endpoint.clone();
let search_query = self.search_query.clone();
let navigator = ctx.link().navigator().unwrap();
navigator.push(&Route::OSSESearch { query: urlencoding::encode(search_query.as_str()).to_string() });
ctx.link().send_future(async move {
let endpoint = format!("{}/search/{}", api_endpoint, search_query);
let fetched_response = Request::get(endpoint.as_str()).send().await.unwrap();
let fetched_results: Vec = match fetched_response.json().await {
Err(e) => panic!("Im panic: {}", e),
Ok(json) => json,
};
OSSEMessage::SearchFinished(fetched_results)
});
false
},
OSSEMessage::SearchChanged(search_query) => {
self.search_query = search_query;
true
},
OSSEMessage::SearchFinished(search_results) => {
self.results = Some(search_results);
true
},
}
}
fn view(&self, ctx: &Context) -> Html {
let onsubmit = ctx.link().callback(|event: SubmitEvent| {
event.prevent_default();
OSSEMessage::SearchSubmitted
});
let oninput = ctx.link().callback(|event: InputEvent| {
let target: EventTarget = event
.target()
.expect("Event should have a target when dispatched");
let input = target.unchecked_into::().value();
OSSEMessage::SearchChanged(input)
});
let display_results = |maybe_results: &Option>| -> Html {
let maybe_results = maybe_results.as_ref();
if maybe_results.is_none() {
return html! {};
}
let results = maybe_results.unwrap();
if !results.is_empty() {
results
.iter()
.sorted()
.map(|r| {
html! {
}
})
.collect::()
} else {
html! {
{"No results!"}
}
}
};
html! {
<>
//SET AT MIDDLE OF VIEWPORT IF NO SEARCHING AND TOP 25% IF SEARCHING
{"OSSE"}
{"Your favorite independent search engine."}
{display_results(&self.results)}
>
}
}
}
//Your favorite search engine in navbar
//Search in middle