desktop/src-tauri/src/picker/manager.rs

76 lines
2.5 KiB
Rust
Raw Normal View History

use futures::{stream::FuturesUnordered, StreamExt};
use once_cell::sync::OnceCell;
use paris::info;
use scrap::Display;
2022-12-17 19:31:22 +08:00
use std::{sync::Arc, borrow::Borrow};
use tokio::{sync::Mutex, task};
2022-12-17 19:31:22 +08:00
use crate::picker::{config, screen::Screen};
2022-12-17 19:31:22 +08:00
use super::{config::DisplayConfig, display_picker::DisplayPicker, screenshot::Screenshot};
pub struct Picker {
pub screens: Arc<Mutex<Vec<Screen>>>,
pub screenshots: Arc<Mutex<Vec<Screenshot>>>,
pub display_configs: Arc<Mutex<Vec<DisplayConfig>>>,
}
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,
)),
})
}
pub async fn list_displays(&self) -> anyhow::Result<Vec<String>> {
let mut configs = self.display_configs.lock().await;
let displays = Display::all()
.map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?;
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() {
futs.push(async move {
2022-12-17 19:31:22 +08:00
let join = task::spawn(Self::preview_display_by_config(config.clone()));
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);
}
}
}
Ok(bitmap_string_list)
}
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)
}
}