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

98 lines
3.1 KiB
Rust

use futures::{stream::FuturesUnordered, StreamExt};
use paris::info;
use scrap::Display;
use std::sync::Arc;
use tokio::{
sync::{Mutex, OnceCell},
task,
};
use crate::picker::{config, screen::Screen};
use super::{
config::DisplayConfig,
display_picker::DisplayPicker,
screenshot::{Screenshot, ScreenshotDto},
};
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 async fn global() -> &'static Picker {
static SCREEN_COLOR_PICKER: OnceCell<Picker> = OnceCell::const_new();
SCREEN_COLOR_PICKER
.get_or_init(|| async {
Picker {
screens: Arc::new(Mutex::new(vec![])),
screenshots: Arc::new(Mutex::new(vec![])),
display_configs: Arc::new(Mutex::new(
config::Manager::global().get_config().await.display_configs,
)),
}
})
.await
}
pub async fn list_displays(&self) -> anyhow::Result<Vec<ScreenshotDto>> {
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, index, width, height);
configs.push(config);
}
for config in configs.iter() {
futs.push(async move {
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<ScreenshotDto> {
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_dto().await)
}
pub async fn get_screenshot_by_config(
&self,
config: DisplayConfig,
) -> anyhow::Result<ScreenshotDto> {
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_dto().await)
}
}