2022-11-28 00:09:18 +08:00
|
|
|
use futures::{stream::FuturesUnordered, StreamExt};
|
2022-11-20 20:09:25 +08:00
|
|
|
use once_cell::sync::OnceCell;
|
2022-11-28 00:09:18 +08:00
|
|
|
use paris::info;
|
|
|
|
use scrap::Display;
|
2022-12-17 19:31:22 +08:00
|
|
|
use std::{sync::Arc, borrow::Borrow};
|
2022-11-28 00:09:18 +08:00
|
|
|
use tokio::{sync::Mutex, task};
|
2022-11-20 20:09:25 +08:00
|
|
|
|
2022-12-17 19:31:22 +08:00
|
|
|
use crate::picker::{config, screen::Screen};
|
2022-11-20 20:09:25 +08:00
|
|
|
|
2022-12-17 19:31:22 +08:00
|
|
|
use super::{config::DisplayConfig, display_picker::DisplayPicker, screenshot::Screenshot};
|
2022-11-20 20:09:25 +08:00
|
|
|
|
|
|
|
pub struct Picker {
|
|
|
|
pub screens: Arc<Mutex<Vec<Screen>>>,
|
|
|
|
pub screenshots: Arc<Mutex<Vec<Screenshot>>>,
|
2022-11-28 00:09:18 +08:00
|
|
|
pub display_configs: Arc<Mutex<Vec<DisplayConfig>>>,
|
2022-11-20 20:09:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Picker {
|
|
|
|
pub fn global() -> &'static Picker {
|
|
|
|
static SCREEN_COLOR_PICKER: OnceCell<Picker> = OnceCell::new();
|
|
|
|
|
|
|
|
SCREEN_COLOR_PICKER.get_or_init(|| Picker {
|
|
|
|
screens: Arc::new(Mutex::new(vec![])),
|
|
|
|
screenshots: Arc::new(Mutex::new(vec![])),
|
2022-12-17 19:31:22 +08:00
|
|
|
display_configs: Arc::new(Mutex::new(
|
|
|
|
config::Manager::global().get_config().display_configs,
|
|
|
|
)),
|
2022-11-20 20:09:25 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-11-28 00:09:18 +08:00
|
|
|
pub async fn list_displays(&self) -> anyhow::Result<Vec<String>> {
|
|
|
|
let mut configs = self.display_configs.lock().await;
|
|
|
|
|
2022-11-20 20:09:25 +08:00
|
|
|
let displays = Display::all()
|
|
|
|
.map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?;
|
2022-11-28 00:09:18 +08:00
|
|
|
|
|
|
|
configs.clear();
|
|
|
|
let mut futs = FuturesUnordered::new();
|
|
|
|
|
|
|
|
for (index, display) in displays.iter().enumerate() {
|
|
|
|
let height = display.height();
|
|
|
|
let width = display.width();
|
|
|
|
let config = DisplayConfig::default(index, width, height);
|
|
|
|
configs.push(config);
|
|
|
|
}
|
|
|
|
|
2022-12-17 19:31:22 +08:00
|
|
|
for config in configs.iter() {
|
2022-11-28 00:09:18 +08:00
|
|
|
futs.push(async move {
|
2022-12-17 19:31:22 +08:00
|
|
|
let join = task::spawn(Self::preview_display_by_config(config.clone()));
|
2022-11-28 00:09:18 +08:00
|
|
|
join.await?
|
|
|
|
});
|
|
|
|
}
|
|
|
|
let mut bitmap_string_list = vec![];
|
|
|
|
while let Some(bitmap_string) = futs.next().await {
|
|
|
|
match bitmap_string {
|
|
|
|
Ok(bitmap_string) => {
|
|
|
|
bitmap_string_list.push(bitmap_string);
|
|
|
|
}
|
|
|
|
Err(error) => {
|
|
|
|
anyhow::bail!("can not convert to base64 image. {}", error);
|
|
|
|
}
|
|
|
|
}
|
2022-11-20 20:09:25 +08:00
|
|
|
}
|
2022-11-28 00:09:18 +08:00
|
|
|
Ok(bitmap_string_list)
|
|
|
|
}
|
2022-11-20 20:09:25 +08:00
|
|
|
|
2022-11-28 00:09:18 +08:00
|
|
|
pub async fn preview_display_by_config(config: DisplayConfig) -> anyhow::Result<String> {
|
|
|
|
let start = time::Instant::now();
|
|
|
|
let mut picker = DisplayPicker::from_config(config)?;
|
|
|
|
let screenshot = picker.take_screenshot()?;
|
|
|
|
info!("Take Screenshot Spend: {}", start.elapsed());
|
|
|
|
|
|
|
|
anyhow::Ok(screenshot.to_webp_base64().await)
|
|
|
|
}
|
2022-11-20 20:09:25 +08:00
|
|
|
}
|