use std::{collections::BTreeMap, time::Duration}; use deepl::DeepLApi; use relm4::prelude::*; use crate::{ settings::Settings, subtitles::{SUBTITLE_TRACKS, StreamIndex}, translation::TRANSLATIONS, }; pub struct DeeplTranslator { stream_ix: Option, next_cues_to_translate: BTreeMap, } #[derive(Debug)] pub enum DeeplTranslatorMsg { SelectTrack(Option), // this is only used to drive the async translation DoTranslate, } impl AsyncComponent for DeeplTranslator { type Init = (); type Input = DeeplTranslatorMsg; type Output = (); type CommandOutput = (); type Root = (); type Widgets = (); async fn init( _init: Self::Init, _root: Self::Root, sender: relm4::AsyncComponentSender, ) -> AsyncComponentParts { let model = Self { stream_ix: None, next_cues_to_translate: BTreeMap::new(), }; sender.input(DeeplTranslatorMsg::DoTranslate); AsyncComponentParts { model, widgets: () } } async fn update( &mut self, message: Self::Input, sender: AsyncComponentSender, _root: &Self::Root, ) { match message { DeeplTranslatorMsg::SelectTrack(stream_ix) => { self.stream_ix = stream_ix; } DeeplTranslatorMsg::DoTranslate => self.do_translate(sender).await, } } fn init_root() -> Self::Root { () } } impl DeeplTranslator { async fn do_translate(&mut self, sender: AsyncComponentSender) { if let Some(stream_ix) = self.stream_ix { let deepl = DeepLApi::with(&Settings::default().deepl_api_key()).new(); let next_cue_to_translate = self.next_cues_to_translate.entry(stream_ix).or_insert(0); if let Some(cue) = { SUBTITLE_TRACKS .read() .get(&stream_ix) .unwrap() .texts .get(*next_cue_to_translate) .cloned() } { match deepl .translate_text(cue, deepl::Lang::EN) .model_type(deepl::ModelType::PreferQualityOptimized) .await { Ok(mut resp) => { TRANSLATIONS .write() .entry(stream_ix) .or_insert(Vec::new()) .push(resp.translations.pop().unwrap().text); *next_cue_to_translate = *next_cue_to_translate + 1; } Err(e) => { log::error!("error fetching translation: {}", e) } }; } } relm4::tokio::time::sleep(Duration::from_secs(1)).await; sender.input(DeeplTranslatorMsg::DoTranslate); } }