mirror of https://github.com/wayvr-org/wayvr.git
whisper ui
This commit is contained in:
parent
6000986d14
commit
d6713176c6
|
|
@ -28,7 +28,7 @@ use wlx_common::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::{Frontend, FrontendTask, FrontendTasks},
|
frontend::{Frontend, FrontendTask, FrontendTasks},
|
||||||
tab::{settings::macros::MacroParams, Tab, TabType},
|
tab::{Tab, TabType, settings::macros::MacroParams},
|
||||||
views::ViewUpdateParams,
|
views::ViewUpdateParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -246,10 +246,11 @@ impl<T> Tab<T> for TabSettings<T> {
|
||||||
|
|
||||||
// Dropdown handling
|
// Dropdown handling
|
||||||
if let TickResult::Action(name) = self.context_menu.tick(&mut frontend.layout, &mut self.state)? {
|
if let TickResult::Action(name) = self.context_menu.tick(&mut frontend.layout, &mut self.state)? {
|
||||||
if name.starts_with(';') && let Some(tab) = self.current_tab.as_mut() {
|
if name.starts_with(';')
|
||||||
|
&& let Some(tab) = self.current_tab.as_mut()
|
||||||
|
{
|
||||||
let config = frontend.interface.general_config(data);
|
let config = frontend.interface.general_config(data);
|
||||||
tab.context_menu_custom(name, config, &mut frontend.layout, &mut self.state)?;
|
tab.context_menu_custom(name, config, &mut frontend.layout, &mut self.state)?;
|
||||||
|
|
||||||
} else if let (Some(setting), Some(id), Some(value), Some(text), Some(translated)) = {
|
} else if let (Some(setting), Some(id), Some(value), Some(text), Some(translated)) = {
|
||||||
let mut s = name.splitn(5, ';');
|
let mut s = name.splitn(5, ';');
|
||||||
(s.next(), s.next(), s.next(), s.next(), s.next())
|
(s.next(), s.next(), s.next(), s.next(), s.next())
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,30 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use wgui::{
|
use wgui::{
|
||||||
components::button::{ButtonClickEvent, ComponentButton}, globals::WguiGlobals, i18n::Translation, layout::WidgetID, log::LogErr, parser::{Fetchable, TemplateParams}, task::Tasks, widget::label::WidgetLabel, windowing::context_menu::{self}
|
components::button::{ButtonClickEvent, ComponentButton},
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::WidgetID,
|
||||||
|
log::LogErr,
|
||||||
|
parser::{Fetchable, TemplateParams},
|
||||||
|
task::Tasks,
|
||||||
|
widget::label::WidgetLabel,
|
||||||
|
windowing::context_menu::{self},
|
||||||
};
|
};
|
||||||
use wlx_common::{async_executor::AsyncExecutor, config::GeneralConfig};
|
use wlx_common::{async_executor::AsyncExecutor, config::GeneralConfig};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::FrontendTasks,
|
frontend::FrontendTasks,
|
||||||
tab::settings::{
|
tab::settings::{
|
||||||
SettingType, SettingsMountParams, SettingsTab, TabNameEnum, Task as ParentTask, horiz_cell, macros::{MacroParams, options_category, options_checkbox, options_range_f32}
|
SettingType, SettingsMountParams, SettingsTab, TabNameEnum, Task as ParentTask, horiz_cell,
|
||||||
|
macros::{MacroParams, options_category, options_checkbox, options_range_f32},
|
||||||
},
|
},
|
||||||
util::{
|
util::{
|
||||||
popup_manager::PopupHolder,
|
popup_manager::PopupHolder,
|
||||||
whisper::{WHISPER_MODELS, WhisperModel, whisper_any_models_downloaded, whisper_delete_all_models, whisper_model_from_name, whisper_model_path},
|
whisper::{
|
||||||
|
WHISPER_MODELS, WhisperModel, whisper_any_models_downloaded, whisper_delete_all_models, whisper_model_from_name,
|
||||||
|
whisper_model_path,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
views::{self, ViewUpdateParams},
|
views::{self, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
@ -24,6 +36,7 @@ enum Task {
|
||||||
WhisperDownload(&'static WhisperModel),
|
WhisperDownload(&'static WhisperModel),
|
||||||
WhisperDownloadDone,
|
WhisperDownloadDone,
|
||||||
CloseDialog,
|
CloseDialog,
|
||||||
|
ReloadTab,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
|
@ -48,24 +61,32 @@ impl SettingsTab for State {
|
||||||
if !whisper_model_path(model.file_name).exists() {
|
if !whisper_model_path(model.file_name).exists() {
|
||||||
// download failed, set to selection to none
|
// download failed, set to selection to none
|
||||||
par.general_config.whisper_model = "".into();
|
par.general_config.whisper_model = "".into();
|
||||||
// re-init the whole tab
|
// reload the tab
|
||||||
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task::WhisperRemoveUnused => {
|
Task::WhisperRemoveUnused => {
|
||||||
let _ = whisper_delete_all_models().log_err("could not remove whisper models");
|
let _ = whisper_delete_all_models().log_err("could not remove whisper models");
|
||||||
},
|
}
|
||||||
Task::WhisperDownload(model) => {
|
Task::WhisperDownload(model) => {
|
||||||
self.pending_download = Some(model);
|
self.pending_download = Some(model);
|
||||||
self.show_whisper_download_dialog(model, par.executor.clone());
|
self.show_whisper_download_dialog(model, par.executor.clone());
|
||||||
},
|
}
|
||||||
Task::WhisperDownloadDone => {
|
Task::WhisperDownloadDone => {
|
||||||
// we're happy
|
if let Some(model) = self.pending_download.take() {
|
||||||
},
|
par.general_config.whisper_model = model.file_name.into();
|
||||||
|
|
||||||
|
// reload tab so that the downloaded checkmarks get populated
|
||||||
|
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||||
|
}
|
||||||
|
}
|
||||||
Task::CloseDialog => {
|
Task::CloseDialog => {
|
||||||
let close_dialog = self.popup_dialog.get_close_callback(par.layout);
|
let close_dialog = self.popup_dialog.get_close_callback(par.layout);
|
||||||
close_dialog();
|
close_dialog();
|
||||||
|
}
|
||||||
|
Task::ReloadTab => {
|
||||||
|
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -84,19 +105,27 @@ impl SettingsTab for State {
|
||||||
let mut s = action.splitn(3, ';');
|
let mut s = action.splitn(3, ';');
|
||||||
(s.next(), s.next(), s.next())
|
(s.next(), s.next(), s.next())
|
||||||
} {
|
} {
|
||||||
if !model_name.is_empty() && let Some(model) = whisper_model_from_name(model_name)
|
if !model_name.is_empty()
|
||||||
{
|
&& let Some(model) = whisper_model_from_name(model_name)
|
||||||
let mut common = layout.common();
|
{
|
||||||
let mut label = state.fetch_widget_as::<WidgetLabel>(common.state, &format!("{id}_value"))?;
|
let mut common = layout.common();
|
||||||
label.set_text(&mut common, Translation::from_raw_text(model.display_name));
|
let mut label = state.fetch_widget_as::<WidgetLabel>(common.state, &format!("{id}_value"))?;
|
||||||
|
label.set_text(&mut common, Translation::from_raw_text(model.display_name));
|
||||||
config.whisper_model = action.as_ref().into();
|
|
||||||
|
config.whisper_model = model.file_name.into();
|
||||||
self.show_whisper_model_dialog_box_download(model)?;
|
if !whisper_model_path(model.file_name).exists() {
|
||||||
} else if whisper_any_models_downloaded().unwrap_or_default() {
|
self.show_whisper_model_dialog_box_download(model)?;
|
||||||
self.show_whisper_model_dialog_box_cleanup()?;
|
}
|
||||||
|
} else {
|
||||||
|
config.whisper_model = "".into();
|
||||||
|
// re-init the whole tab
|
||||||
|
if whisper_any_models_downloaded().unwrap_or_default() {
|
||||||
|
self.show_whisper_model_dialog_box_cleanup()?;
|
||||||
|
} else {
|
||||||
|
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +174,7 @@ impl State {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_whisper_download_dialog(&mut self, model: &WhisperModel, executor: AsyncExecutor) {
|
fn show_whisper_download_dialog(&mut self, model: &WhisperModel, executor: AsyncExecutor) {
|
||||||
views::download_file::mount_popup(
|
views::download_file::mount_popup(
|
||||||
self.popup_download.clone(),
|
self.popup_download.clone(),
|
||||||
self.frontend_tasks.clone(),
|
self.frontend_tasks.clone(),
|
||||||
|
|
@ -174,24 +203,23 @@ impl State {
|
||||||
globals: self.globals.clone(),
|
globals: self.globals.clone(),
|
||||||
message: Translation::from_translation_key("APP_SETTINGS.WHISPER.NEED_TO_DOWNLOAD_MODEL"),
|
message: Translation::from_translation_key("APP_SETTINGS.WHISPER.NEED_TO_DOWNLOAD_MODEL"),
|
||||||
entries: vec![
|
entries: vec![
|
||||||
views::dialog_box::ButtonEntry {
|
views::dialog_box::ButtonEntry {
|
||||||
content: Translation::from_translation_key("APP_SETTINGS.CANCEL"),
|
content: Translation::from_translation_key("APP_SETTINGS.CANCEL"),
|
||||||
icon: "dashboard/close.svg",
|
icon: "dashboard/close.svg",
|
||||||
action: ACTION_CANCEL,
|
action: ACTION_CANCEL,
|
||||||
},
|
},
|
||||||
views::dialog_box::ButtonEntry {
|
views::dialog_box::ButtonEntry {
|
||||||
content: Translation::from_translation_key("DOWNLOAD"),
|
content: Translation::from_translation_key("DOWNLOAD"),
|
||||||
icon: "dashboard/download.svg",
|
icon: "dashboard/download.svg",
|
||||||
action: ACTION_DOWNLOAD,
|
action: ACTION_DOWNLOAD,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
on_action_click: Box::new(move |action| match action {
|
on_action_click: Box::new(move |action| match action {
|
||||||
ACTION_DOWNLOAD => {
|
ACTION_DOWNLOAD => {
|
||||||
tasks.push(Task::WhisperDownload(model));
|
tasks.push(Task::WhisperDownload(model));
|
||||||
}
|
}
|
||||||
ACTION_CANCEL => {
|
ACTION_CANCEL => {
|
||||||
tasks.push(Task::CloseDialog);
|
tasks.push(Task::CloseDialog);
|
||||||
|
|
||||||
// treat as failed download
|
// treat as failed download
|
||||||
tasks.push(Task::WhisperDownloadClosed);
|
tasks.push(Task::WhisperDownloadClosed);
|
||||||
}
|
}
|
||||||
|
|
@ -216,23 +244,26 @@ impl State {
|
||||||
globals: self.globals.clone(),
|
globals: self.globals.clone(),
|
||||||
message: Translation::from_translation_key("APP_SETTINGS.WHISPER.REMOVE_UNUSED_MODELS"),
|
message: Translation::from_translation_key("APP_SETTINGS.WHISPER.REMOVE_UNUSED_MODELS"),
|
||||||
entries: vec![
|
entries: vec![
|
||||||
views::dialog_box::ButtonEntry {
|
views::dialog_box::ButtonEntry {
|
||||||
content: Translation::from_translation_key("APP_SETTINGS.CANCEL"),
|
content: Translation::from_translation_key("APP_SETTINGS.CANCEL"),
|
||||||
icon: "dashboard/close.svg",
|
icon: "dashboard/close.svg",
|
||||||
action: ACTION_CANCEL,
|
action: ACTION_CANCEL,
|
||||||
},
|
},
|
||||||
views::dialog_box::ButtonEntry {
|
views::dialog_box::ButtonEntry {
|
||||||
content: Translation::from_translation_key("REMOVE"),
|
content: Translation::from_translation_key("REMOVE"),
|
||||||
icon: "dashboard/trash.svg",
|
icon: "dashboard/trash.svg",
|
||||||
action: ACTION_REMOVE,
|
action: ACTION_REMOVE,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
on_action_click: Box::new(move |action| match action {
|
on_action_click: Box::new(move |action| match action {
|
||||||
ACTION_REMOVE => {
|
ACTION_REMOVE => {
|
||||||
tasks.push(Task::WhisperRemoveUnused);
|
tasks.push(Task::WhisperRemoveUnused);
|
||||||
|
tasks.push(Task::CloseDialog);
|
||||||
|
tasks.push(Task::ReloadTab);
|
||||||
}
|
}
|
||||||
ACTION_CANCEL => {
|
ACTION_CANCEL => {
|
||||||
tasks.push(Task::CloseDialog);
|
tasks.push(Task::CloseDialog);
|
||||||
|
tasks.push(Task::ReloadTab);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -249,6 +280,13 @@ fn whisper_models_dropdown(mp: &mut MacroParams, parent: WidgetID) -> anyhow::Re
|
||||||
|
|
||||||
let parent = horiz_cell(mp.layout, parent)?;
|
let parent = horiz_cell(mp.layout, parent)?;
|
||||||
|
|
||||||
|
let mut downloaded_models = vec![];
|
||||||
|
for (idx, m) in WHISPER_MODELS.iter().enumerate() {
|
||||||
|
if whisper_model_path(m.file_name).exists() {
|
||||||
|
downloaded_models.push(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let current_file = mp.config.whisper_model.as_ref();
|
let current_file = mp.config.whisper_model.as_ref();
|
||||||
let current_translation = whisper_model_from_name(current_file)
|
let current_translation = whisper_model_from_name(current_file)
|
||||||
.map_or(Translation::from_translation_key("APP_SETTINGS.OPTION.NONE"), |x| {
|
.map_or(Translation::from_translation_key("APP_SETTINGS.OPTION.NONE"), |x| {
|
||||||
|
|
@ -276,9 +314,14 @@ fn whisper_models_dropdown(mp: &mut MacroParams, parent: WidgetID) -> anyhow::Re
|
||||||
move |_common, e: ButtonClickEvent| {
|
move |_common, e: ButtonClickEvent| {
|
||||||
let mut cells = WHISPER_MODELS
|
let mut cells = WHISPER_MODELS
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| context_menu::Cell {
|
.enumerate()
|
||||||
|
.map(|(idx, item)| context_menu::Cell {
|
||||||
action_name: Some(format!(";{id};{}", item.file_name).into()),
|
action_name: Some(format!(";{id};{}", item.file_name).into()),
|
||||||
title: Translation::from_raw_text(item.display_name),
|
title: Translation::from_raw_text_string(format!(
|
||||||
|
"{}{}",
|
||||||
|
item.display_name,
|
||||||
|
if downloaded_models.contains(&idx) { " ✅" } else { "" }
|
||||||
|
)),
|
||||||
tooltip: None,
|
tooltip: None,
|
||||||
attribs: vec![],
|
attribs: vec![],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,8 @@ async fn fetch_and_follow_redirects(
|
||||||
fn uri_try_from_str(s: &str) -> anyhow::Result<hyper::http::uri::PathAndQuery> {
|
fn uri_try_from_str(s: &str) -> anyhow::Result<hyper::http::uri::PathAndQuery> {
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
let uri: hyper::Uri = s.try_into().context("invalid URI")?;
|
let uri: hyper::Uri = s.try_into().context("invalid URI")?;
|
||||||
uri.path_and_query()
|
uri
|
||||||
|
.path_and_query()
|
||||||
.ok_or_else(|| anyhow::anyhow!("URI has no path and query component"))
|
.ok_or_else(|| anyhow::anyhow!("URI has no path and query component"))
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +184,9 @@ async fn follow_single_redirect(
|
||||||
hyper::Uri::try_from(location_str).context("invalid redirect location")?
|
hyper::Uri::try_from(location_str).context("invalid redirect location")?
|
||||||
} else {
|
} else {
|
||||||
let mut parts = original_uri.into_parts();
|
let mut parts = original_uri.into_parts();
|
||||||
parts.path_and_query = uri_try_from_str(location_str).context("invalid redirect location")?.into();
|
parts.path_and_query = uri_try_from_str(location_str)
|
||||||
|
.context("invalid redirect location")?
|
||||||
|
.into();
|
||||||
hyper::Uri::from_parts(parts).context("failed to construct redirect URI")?
|
hyper::Uri::from_parts(parts).context("failed to construct redirect URI")?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ pub mod cache_dir;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod config_io;
|
pub mod config_io;
|
||||||
pub mod data_dir;
|
|
||||||
pub mod dash_interface;
|
pub mod dash_interface;
|
||||||
pub mod dash_interface_emulated;
|
pub mod dash_interface_emulated;
|
||||||
|
pub mod data_dir;
|
||||||
pub mod desktop_finder;
|
pub mod desktop_finder;
|
||||||
mod handle;
|
mod handle;
|
||||||
pub mod locale;
|
pub mod locale;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue