feat(web): specify icon
This commit is contained in:
parent
790ab0b95f
commit
e6f85ca07b
2 changed files with 37 additions and 24 deletions
|
|
@ -44,6 +44,8 @@ pub struct Rule {
|
||||||
pub struct Definition {
|
pub struct Definition {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub query: String,
|
pub query: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub icon: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load() -> Config {
|
pub fn load() -> Config {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use url::Url;
|
||||||
|
|
||||||
use pop_launcher::*;
|
use pop_launcher::*;
|
||||||
|
|
||||||
pub use config::{Config, Definition, load};
|
pub use config::{load, Config, Definition};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
|
@ -91,7 +91,7 @@ impl App {
|
||||||
let (_, mut query) = query.split_at(word.len());
|
let (_, mut query) = query.split_at(word.len());
|
||||||
query = query.trim();
|
query = query.trim();
|
||||||
let encoded = build_query(def, query);
|
let encoded = build_query(def, query);
|
||||||
let icon = self.get_favicon(&def.name, &encoded).await;
|
let icon = self.get_favicon(def).await;
|
||||||
|
|
||||||
crate::send(
|
crate::send(
|
||||||
&mut self.out,
|
&mut self.out,
|
||||||
|
|
@ -115,23 +115,25 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
async fn get_favicon(&self, rule_name: &str, url: &str) -> Option<IconSource> {
|
async fn get_favicon(&self, def: &Definition) -> Option<IconSource> {
|
||||||
let url = Url::parse(url).expect("invalid url");
|
let favicon_path = self.cache.join(format!("{}.ico", def.name));
|
||||||
|
|
||||||
let favicon_path = self.cache.join(format!("{}.ico", rule_name));
|
|
||||||
|
|
||||||
if favicon_path.exists() {
|
if favicon_path.exists() {
|
||||||
let favicon_path = favicon_path.to_string_lossy().into_owned();
|
let favicon_path = favicon_path.to_string_lossy().into_owned();
|
||||||
Some(IconSource::Name(Cow::Owned(favicon_path)))
|
Some(IconSource::Name(Cow::Owned(favicon_path)))
|
||||||
} else {
|
} else {
|
||||||
self.fetch_icon_in_background(url, &favicon_path).await;
|
self.fetch_icon_in_background(def, &favicon_path).await;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_icon_in_background(&self, url: Url, favicon_path: &Path) {
|
async fn fetch_icon_in_background(&self, def: &Definition, favicon_path: &Path) {
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
|
|
||||||
|
let url = build_query(def, "");
|
||||||
|
let url = Url::parse(&url).expect("invalid url");
|
||||||
|
let icon_source = def.icon.clone();
|
||||||
|
|
||||||
let domain = url
|
let domain = url
|
||||||
.domain()
|
.domain()
|
||||||
.map(|domain| domain.to_string())
|
.map(|domain| domain.to_string())
|
||||||
|
|
@ -147,24 +149,33 @@ impl App {
|
||||||
let fetch =
|
let fetch =
|
||||||
|url: String| async move { fetch_favicon(&url, favicon_path, client).await };
|
|url: String| async move { fetch_favicon(&url, favicon_path, client).await };
|
||||||
|
|
||||||
// Searches for the favicon if it's not defined at the root of the domain.
|
// Generate List of Icon sources in order of priority
|
||||||
let result = match favicon_from_page(&domain, client).await {
|
let mut icon_sources = vec![
|
||||||
Some(url) => fetch(url).await,
|
// First use the defined icon source, if it is defined
|
||||||
|
Some(icon_source)
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(|url| fetch(url)),
|
||||||
|
// Searches for the favicon if it's not defined at the root of the domain.
|
||||||
|
favicon_from_page(&domain, client)
|
||||||
|
.await
|
||||||
|
.map(|url| fetch(url)),
|
||||||
// If not found, fetch from root domain.
|
// If not found, fetch from root domain.
|
||||||
None => match fetch(["https://", &domain, "/favicon.ico"].concat()).await {
|
Some(fetch(["https://", &domain, "/favicon.ico"].concat())),
|
||||||
Some(favicon) => Some(favicon),
|
// If all else fails, try Google.
|
||||||
|
Some(fetch(format!(
|
||||||
|
"https://www.google.com/s2/favicons?domain={}&sz=32",
|
||||||
|
domain
|
||||||
|
))),
|
||||||
|
];
|
||||||
|
|
||||||
// If all else fails, try Google.
|
// await every single source and take the first one, which does not return None
|
||||||
None => {
|
let mut result = None;
|
||||||
fetch(format!(
|
for f in icon_sources.drain(..).flatten() {
|
||||||
"https://www.google.com/s2/favicons?domain={}&sz=32",
|
if let res @ Some(_) = f.await {
|
||||||
domain
|
result = res;
|
||||||
))
|
break;
|
||||||
.await
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Some(icon) => {
|
Some(icon) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue