mirror of
https://github.com/project-gauntlet/gauntlet.git
synced 2025-12-23 10:35:53 +00:00
Merge settings app into the main app
This commit is contained in:
parent
136b2c2ab6
commit
f41ab9233b
43 changed files with 679 additions and 1420 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
|
@ -4500,7 +4500,6 @@ dependencies = [
|
|||
"clap",
|
||||
"gauntlet-client",
|
||||
"gauntlet-common",
|
||||
"gauntlet-management-client",
|
||||
"gauntlet-plugin-runtime",
|
||||
"gauntlet-server",
|
||||
"gauntlet-utils",
|
||||
|
|
@ -4598,21 +4597,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gauntlet-management-client"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gauntlet-common",
|
||||
"gauntlet-common-ui",
|
||||
"gauntlet-utils",
|
||||
"iced",
|
||||
"iced_fonts",
|
||||
"itertools 0.13.0",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gauntlet-manifest-schema"
|
||||
version = "0.0.0"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ repository = "https://github.com/project-gauntlet/gauntlet"
|
|||
|
||||
[workspace]
|
||||
members = [
|
||||
"rust/management_client",
|
||||
"rust/client",
|
||||
"rust/server",
|
||||
"rust/common",
|
||||
|
|
@ -35,7 +34,6 @@ gauntlet-common = { path = "./rust/common" }
|
|||
gauntlet-common-ui = { path = "./rust/common_ui" }
|
||||
gauntlet-common-plugin-runtime = { path = "./rust/common_plugin_runtime" }
|
||||
gauntlet-plugin-runtime = { path = "./rust/plugin_runtime" }
|
||||
gauntlet-management-client = { path = "./rust/management_client" }
|
||||
gauntlet-client = { path = "./rust/client" }
|
||||
gauntlet-server = { path = "./rust/server" }
|
||||
gauntlet-utils = { path = "./rust/utils" }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ edition.workspace = true
|
|||
|
||||
[dependencies]
|
||||
# workspaces
|
||||
gauntlet-management-client.workspace = true
|
||||
gauntlet-client.workspace = true
|
||||
gauntlet-server.workspace = true
|
||||
gauntlet-plugin-runtime.workspace = true
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ use std::time::UNIX_EPOCH;
|
|||
|
||||
use clap::Parser;
|
||||
use gauntlet_common::cli::is_server_running;
|
||||
use gauntlet_common::cli::open_settings_window;
|
||||
use gauntlet_common::cli::open_window;
|
||||
use gauntlet_common::cli::run_action;
|
||||
use gauntlet_common::dirs::Dirs;
|
||||
use gauntlet_management_client::start_management_client;
|
||||
use gauntlet_server::PLUGIN_CONNECT_ENV;
|
||||
use gauntlet_server::PLUGIN_UUID_ENV;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
|
@ -110,7 +110,7 @@ pub fn init() {
|
|||
Some(command) => {
|
||||
match command {
|
||||
Commands::Open => open_window(),
|
||||
Commands::Settings => start_management_client(),
|
||||
Commands::Settings => open_settings_window(),
|
||||
Commands::Run {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ use iced::widget::text;
|
|||
use iced::widget::text::Shaping;
|
||||
use iced::widget::text_input;
|
||||
use iced::widget::text_input::focus;
|
||||
use iced::widget::themer;
|
||||
use iced::window;
|
||||
use iced_fonts::BOOTSTRAP_FONT_BYTES;
|
||||
|
||||
|
|
@ -68,6 +69,7 @@ mod custom_widgets;
|
|||
mod grid_navigation;
|
||||
mod scroll_handle;
|
||||
mod search_list;
|
||||
mod settings;
|
||||
mod state;
|
||||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||
mod sys_tray;
|
||||
|
|
@ -89,6 +91,13 @@ use crate::ui::scenario_runner::ScenarioRunnerMsg;
|
|||
use crate::ui::scenario_runner::handle_scenario_runner_msg;
|
||||
use crate::ui::scroll_handle::ScrollHandle;
|
||||
use crate::ui::server::handle_server_message;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::ui::SettingsMsg;
|
||||
use crate::ui::settings::ui::SettingsParams;
|
||||
use crate::ui::settings::ui::SettingsWindowState;
|
||||
use crate::ui::settings::ui::subscription_settings;
|
||||
use crate::ui::settings::ui::update_settings;
|
||||
use crate::ui::settings::ui::view_settings;
|
||||
use crate::ui::state::ErrorViewData;
|
||||
use crate::ui::state::Focus;
|
||||
use crate::ui::state::GlobalState;
|
||||
|
|
@ -100,8 +109,8 @@ use crate::ui::widget::action_panel::ActionPanel;
|
|||
use crate::ui::widget::action_panel::ActionPanelItem;
|
||||
use crate::ui::widget::events::ComponentWidgetEvent;
|
||||
use crate::ui::widget::root::render_root;
|
||||
use crate::ui::windows::MainWindowState;
|
||||
use crate::ui::windows::WindowActionMsg;
|
||||
use crate::ui::windows::WindowState;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::ui::windows::x11_focus::x11_linux_focus_change_subscription;
|
||||
|
||||
|
|
@ -112,7 +121,8 @@ pub struct AppModel {
|
|||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||
_tray_icon: tray_icon::TrayIcon,
|
||||
theme: GauntletComplexTheme,
|
||||
window: WindowState,
|
||||
main_window_state: MainWindowState,
|
||||
settings_window_state: SettingsWindowState,
|
||||
|
||||
// ephemeral state
|
||||
prompt: String,
|
||||
|
|
@ -197,10 +207,7 @@ pub enum AppMsg {
|
|||
plugin_preferences_required: bool,
|
||||
entrypoint_preferences_required: bool,
|
||||
},
|
||||
OpenSettingsPreferences {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
},
|
||||
OpenSettings(SettingsParams),
|
||||
OnOpenView {
|
||||
action_shortcuts: HashMap<String, PhysicalShortcut>,
|
||||
},
|
||||
|
|
@ -278,6 +285,7 @@ pub enum AppMsg {
|
|||
display: String,
|
||||
},
|
||||
HandleScenario(ScenarioRunnerMsg),
|
||||
Settings(SettingsMsg),
|
||||
}
|
||||
|
||||
pub fn run(minimized: bool, scenario_runner_data: Option<ScenarioRunnerData>) {
|
||||
|
|
@ -333,7 +341,7 @@ fn new(minimized: bool, #[allow(unused)] scenario_runner_data: Option<ScenarioRu
|
|||
|
||||
let client_context = ClientContext::new();
|
||||
let global_state = GlobalState::new(text_input::Id::unique());
|
||||
let window = WindowState::new(
|
||||
let window = MainWindowState::new(
|
||||
setup_data.window_position_file,
|
||||
setup_data.close_on_unfocus,
|
||||
setup_data.window_position_mode,
|
||||
|
|
@ -342,6 +350,13 @@ fn new(minimized: bool, #[allow(unused)] scenario_runner_data: Option<ScenarioRu
|
|||
#[cfg(target_os = "linux")]
|
||||
layer_shell,
|
||||
);
|
||||
let settings_state = SettingsWindowState::new(
|
||||
application_manager.clone(),
|
||||
#[cfg(target_os = "linux")]
|
||||
wayland,
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
false,
|
||||
);
|
||||
|
||||
(
|
||||
AppModel {
|
||||
|
|
@ -351,7 +366,8 @@ fn new(minimized: bool, #[allow(unused)] scenario_runner_data: Option<ScenarioRu
|
|||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||
_tray_icon: sys_tray::create_tray(application_manager.clone()),
|
||||
theme,
|
||||
window,
|
||||
main_window_state: window,
|
||||
settings_window_state: settings_state,
|
||||
|
||||
// ephemeral state
|
||||
prompt: "".to_string(),
|
||||
|
|
@ -368,10 +384,10 @@ fn new(minimized: bool, #[allow(unused)] scenario_runner_data: Option<ScenarioRu
|
|||
}
|
||||
|
||||
fn title(state: &AppModel, window: window::Id) -> String {
|
||||
if Some(window) == state.window.main_window_id {
|
||||
"Gauntlet".to_owned()
|
||||
} else {
|
||||
"Gauntlet HUD".to_owned()
|
||||
match window {
|
||||
_ if Some(window) == state.main_window_state.main_window_id => "Gauntlet".to_owned(),
|
||||
_ if Some(window) == state.settings_window_state.settings_window_id => "Gauntlet Settings".to_owned(),
|
||||
_ => "Gauntlet HUD".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -648,7 +664,7 @@ fn update(state: &mut AppModel, message: AppMsg) -> Task<AppMsg> {
|
|||
}
|
||||
}
|
||||
AppMsg::IcedEvent(window_id, Event::Keyboard(event)) => {
|
||||
let Some(main_window_id) = state.window.main_window_id else {
|
||||
let Some(main_window_id) = state.main_window_state.main_window_id else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
|
|
@ -742,13 +758,20 @@ fn update(state: &mut AppModel, message: AppMsg) -> Task<AppMsg> {
|
|||
}
|
||||
}
|
||||
AppMsg::IcedEvent(window_id, Event::Window(window::Event::Focused)) => {
|
||||
state.window.handle_focused_event(window_id)
|
||||
state.main_window_state.handle_focused_event(window_id)
|
||||
}
|
||||
AppMsg::IcedEvent(window_id, Event::Window(window::Event::Unfocused)) => {
|
||||
state.window.handle_unfocused_event(window_id)
|
||||
state.main_window_state.handle_unfocused_event(window_id)
|
||||
}
|
||||
AppMsg::IcedEvent(window_id, Event::Window(window::Event::Moved(point))) => {
|
||||
state.window.handle_move_event(window_id, point)
|
||||
state.main_window_state.handle_move_event(window_id, point)
|
||||
}
|
||||
AppMsg::IcedEvent(window_id, Event::Window(window::Event::Closed)) => {
|
||||
if state.settings_window_state.settings_window_id == Some(window_id) {
|
||||
Task::done(AppMsg::Settings(SettingsMsg::WindowDestroyed))
|
||||
} else {
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
AppMsg::IcedEvent(_, _) => Task::none(),
|
||||
AppMsg::WidgetEvent {
|
||||
|
|
@ -807,10 +830,7 @@ fn update(state: &mut AppModel, message: AppMsg) -> Task<AppMsg> {
|
|||
},
|
||||
)
|
||||
}
|
||||
AppMsg::OpenSettingsPreferences {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => state.open_settings_window_preferences(plugin_id, entrypoint_id),
|
||||
AppMsg::OpenSettings(params) => Task::done(AppMsg::Settings(SettingsMsg::OpenSettings(params))),
|
||||
AppMsg::OnOpenView { action_shortcuts } => {
|
||||
match &mut state.global_state {
|
||||
GlobalState::MainView {
|
||||
|
|
@ -1086,7 +1106,7 @@ fn update(state: &mut AppModel, message: AppMsg) -> Task<AppMsg> {
|
|||
Task::none()
|
||||
}
|
||||
AppMsg::FocusPluginViewSearchBar { widget_id } => state.client_context.focus_search_bar(widget_id),
|
||||
AppMsg::WindowAction(action) => state.window.handle_action(action),
|
||||
AppMsg::WindowAction(action) => state.main_window_state.handle_action(action),
|
||||
AppMsg::SetTheme { theme } => {
|
||||
state.theme = GauntletComplexTheme::new(theme);
|
||||
|
||||
|
|
@ -1192,17 +1212,28 @@ fn update(state: &mut AppModel, message: AppMsg) -> Task<AppMsg> {
|
|||
Task::none()
|
||||
}
|
||||
AppMsg::HandleScenario(msg) => {
|
||||
handle_scenario_runner_msg(msg, state.application_manager.clone(), state.window.main_window_id)
|
||||
.map(AppMsg::HandleScenario)
|
||||
handle_scenario_runner_msg(
|
||||
msg,
|
||||
state.application_manager.clone(),
|
||||
state.main_window_state.main_window_id,
|
||||
)
|
||||
.map(AppMsg::HandleScenario)
|
||||
}
|
||||
AppMsg::Settings(msg) => {
|
||||
update_settings(&mut state.settings_window_state, &state.global_hotkey_manager, msg).map(AppMsg::Settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn view(state: &AppModel, window: window::Id) -> Element<'_, AppMsg> {
|
||||
if Some(window) == state.window.main_window_id {
|
||||
view_main(state)
|
||||
} else {
|
||||
view_hud(state)
|
||||
match window {
|
||||
_ if Some(window) == state.main_window_state.main_window_id => view_main(state),
|
||||
_ if Some(window) == state.settings_window_state.settings_window_id => {
|
||||
let themer: Element<_> = themer(GauntletSettingsTheme, view_settings(&state.settings_window_state)).into();
|
||||
|
||||
themer.map(AppMsg::Settings)
|
||||
}
|
||||
_ => view_hud(state),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1257,27 +1288,25 @@ fn view_main(state: &AppModel) -> Element<'_, AppMsg> {
|
|||
"Before using, plugin and entrypoint preferences need to be specified";
|
||||
// note:
|
||||
// we open plugin view and not entrypoint even though both need to be specified
|
||||
let msg = AppMsg::OpenSettingsPreferences {
|
||||
let msg = AppMsg::OpenSettings(SettingsParams::PluginPreferences {
|
||||
plugin_id: plugin_id.clone(),
|
||||
entrypoint_id: None,
|
||||
};
|
||||
});
|
||||
(description_text, msg)
|
||||
}
|
||||
(false, true) => {
|
||||
// TODO do not show "entrypoint" name to user
|
||||
let description_text = "Before using, entrypoint preferences need to be specified";
|
||||
let msg = AppMsg::OpenSettingsPreferences {
|
||||
let msg = AppMsg::OpenSettings(SettingsParams::EntrypointPreferences {
|
||||
plugin_id: plugin_id.clone(),
|
||||
entrypoint_id: Some(entrypoint_id.clone()),
|
||||
};
|
||||
entrypoint_id: entrypoint_id.clone(),
|
||||
});
|
||||
(description_text, msg)
|
||||
}
|
||||
(true, false) => {
|
||||
let description_text = "Before using, plugin preferences need to be specified";
|
||||
let msg = AppMsg::OpenSettingsPreferences {
|
||||
let msg = AppMsg::OpenSettings(SettingsParams::PluginPreferences {
|
||||
plugin_id: plugin_id.clone(),
|
||||
entrypoint_id: None,
|
||||
};
|
||||
});
|
||||
(description_text, msg)
|
||||
}
|
||||
(false, false) => unreachable!(),
|
||||
|
|
@ -1744,7 +1773,9 @@ fn view_main(state: &AppModel) -> Element<'_, AppMsg> {
|
|||
}
|
||||
|
||||
fn subscription(#[allow(unused)] state: &AppModel) -> Subscription<AppMsg> {
|
||||
let events_subscription = event::listen_with(|event, status, window_id| {
|
||||
let mut subscriptions = vec![];
|
||||
|
||||
subscriptions.push(event::listen_with(|event, status, window_id| {
|
||||
match status {
|
||||
event::Status::Ignored => Some(AppMsg::IcedEvent(window_id, event)),
|
||||
event::Status::Captured => {
|
||||
|
|
@ -1757,25 +1788,23 @@ fn subscription(#[allow(unused)] state: &AppModel) -> Subscription<AppMsg> {
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut subscriptions = vec![
|
||||
Subscription::run(|| {
|
||||
stream::channel(10, async move |sender| {
|
||||
register_global_shortcut_listener(sender.clone());
|
||||
subscriptions.push(Subscription::run(|| {
|
||||
stream::channel(10, async move |sender| {
|
||||
register_global_shortcut_listener(sender.clone());
|
||||
|
||||
std::future::pending::<()>().await;
|
||||
std::future::pending::<()>().await;
|
||||
|
||||
unreachable!()
|
||||
})
|
||||
.map(AppMsg::HandleGlobalShortcut)
|
||||
}),
|
||||
events_subscription,
|
||||
];
|
||||
unreachable!()
|
||||
})
|
||||
.map(AppMsg::HandleGlobalShortcut)
|
||||
}));
|
||||
|
||||
subscriptions.push(subscription_settings(&state.settings_window_state).map(AppMsg::Settings));
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
if !state.window.wayland {
|
||||
if !state.main_window_state.wayland {
|
||||
subscriptions.push(x11_linux_focus_change_subscription())
|
||||
}
|
||||
|
||||
|
|
@ -1951,17 +1980,6 @@ impl AppModel {
|
|||
Task::done(msg)
|
||||
}
|
||||
|
||||
fn open_settings_window_preferences(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
) -> Task<AppMsg> {
|
||||
self.application_manager
|
||||
.open_settings_window_preferences(plugin_id, entrypoint_id);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn inline_view_shortcuts(&self) -> Task<AppMsg> {
|
||||
let result = self
|
||||
.application_manager
|
||||
|
|
@ -1998,11 +2016,7 @@ impl AppModel {
|
|||
modifier_control: cfg!(not(target_os = "macos")),
|
||||
modifier_alt: false,
|
||||
modifier_meta: cfg!(target_os = "macos"),
|
||||
}) => {
|
||||
self.application_manager.open_settings_window();
|
||||
|
||||
Task::none()
|
||||
}
|
||||
}) => Task::done(AppMsg::OpenSettings(SettingsParams::Default)),
|
||||
Some(PhysicalShortcut {
|
||||
physical_key: PhysicalKey::KeyK,
|
||||
modifier_shift: false,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use std::ops::Deref;
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use gauntlet_common::model::UiSetupData;
|
||||
use gauntlet_common::rpc::frontend_api::FrontendApiRequestData;
|
||||
use gauntlet_common::rpc::frontend_api::FrontendApiResponseData;
|
||||
|
|
@ -22,6 +21,7 @@ use tokio::sync::RwLock as TokioRwLock;
|
|||
|
||||
use crate::ui::AppModel;
|
||||
use crate::ui::AppMsg;
|
||||
use crate::ui::settings::ui::SettingsParams;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::ui::wayland::layer_shell_supported;
|
||||
use crate::ui::windows::WindowActionMsg;
|
||||
|
|
@ -234,6 +234,11 @@ async fn request_loop(
|
|||
action_index,
|
||||
}
|
||||
}
|
||||
FrontendApiRequestData::ShowSettings {} => {
|
||||
responder.respond(Ok(FrontendApiResponseData::ShowSettings { data: () }));
|
||||
|
||||
AppMsg::OpenSettings(SettingsParams::Default)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -260,9 +265,7 @@ pub fn handle_server_message(
|
|||
ServerGrpcApiRequestData::ShowSettingsWindow {} => {
|
||||
responder.respond(Ok(ServerGrpcApiResponseData::ShowSettingsWindow { data: () }));
|
||||
|
||||
state.application_manager.open_settings_window();
|
||||
|
||||
Task::none()
|
||||
Task::done(AppMsg::OpenSettings(SettingsParams::Default))
|
||||
}
|
||||
ServerGrpcApiRequestData::RunAction {
|
||||
plugin_id,
|
||||
|
|
@ -293,230 +296,6 @@ pub fn handle_server_message(
|
|||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::Plugins {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.plugins()
|
||||
.map(|data| ServerGrpcApiResponseData::Plugins { data });
|
||||
|
||||
responder.respond(result.into());
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetPluginState { plugin_id, enabled } => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_plugin_state(plugin_id.clone(), *enabled)
|
||||
.map(|data| ServerGrpcApiResponseData::SetPluginState { data });
|
||||
|
||||
responder.respond(result.into());
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetEntrypointState {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
enabled,
|
||||
} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_entrypoint_state(plugin_id.clone(), entrypoint_id.clone(), *enabled)
|
||||
.map(|data| ServerGrpcApiResponseData::SetEntrypointState { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetGlobalShortcut { shortcut } => {
|
||||
let Some(global_hotkey_manager) = &state.global_hotkey_manager else {
|
||||
responder.respond(Err(anyhow!("Global hotkey manager is disabled")));
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_global_shortcut(global_hotkey_manager, shortcut.clone());
|
||||
|
||||
responder.respond(Ok(ServerGrpcApiResponseData::SetGlobalShortcut { data: result }));
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::GetGlobalShortcut {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.get_global_shortcut()
|
||||
.map(|data| ServerGrpcApiResponseData::GetGlobalShortcut { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetGlobalEntrypointShortcut {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
shortcut,
|
||||
} => {
|
||||
let Some(global_hotkey_manager) = &state.global_hotkey_manager else {
|
||||
responder.respond(Err(anyhow!("Global hotkey manager is disabled")));
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_global_entrypoint_shortcut(
|
||||
global_hotkey_manager,
|
||||
plugin_id.clone(),
|
||||
entrypoint_id.clone(),
|
||||
shortcut.clone(),
|
||||
)
|
||||
.map(|data| ServerGrpcApiResponseData::SetGlobalEntrypointShortcut { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::GetGlobalEntrypointShortcuts {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.get_global_entrypoint_shortcut()
|
||||
.map(|data| ServerGrpcApiResponseData::GetGlobalEntrypointShortcuts { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetEntrypointSearchAlias {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
alias,
|
||||
} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_entrypoint_search_alias(plugin_id.clone(), entrypoint_id.clone(), alias.clone())
|
||||
.map(|data| ServerGrpcApiResponseData::SetEntrypointSearchAlias { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::GetEntrypointSearchAliases {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.get_entrypoint_search_aliases()
|
||||
.map(|data| ServerGrpcApiResponseData::GetEntrypointSearchAliases { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetTheme { theme } => {
|
||||
let application_manager = state.application_manager.clone();
|
||||
let theme = theme.clone();
|
||||
|
||||
Task::future(async move {
|
||||
let result = application_manager
|
||||
.set_theme(theme)
|
||||
.await
|
||||
.map(|data| ServerGrpcApiResponseData::SetTheme { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
AppMsg::Noop
|
||||
})
|
||||
}
|
||||
ServerGrpcApiRequestData::GetTheme {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.get_theme()
|
||||
.map(|data| ServerGrpcApiResponseData::GetTheme { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetWindowPositionMode { mode } => {
|
||||
let application_manager = state.application_manager.clone();
|
||||
let mode = mode.clone();
|
||||
|
||||
Task::future(async move {
|
||||
let result = application_manager
|
||||
.set_window_position_mode(mode)
|
||||
.await
|
||||
.map(|data| ServerGrpcApiResponseData::SetWindowPositionMode { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
AppMsg::Noop
|
||||
})
|
||||
}
|
||||
ServerGrpcApiRequestData::GetWindowPositionMode {} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.get_window_position_mode()
|
||||
.map(|data| ServerGrpcApiResponseData::GetWindowPositionMode { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::SetPreferenceValue {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
preference_id,
|
||||
preference_value,
|
||||
} => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.set_preference_value(
|
||||
plugin_id.clone(),
|
||||
entrypoint_id.clone(),
|
||||
preference_id.clone(),
|
||||
preference_value.clone(),
|
||||
)
|
||||
.map(|data| ServerGrpcApiResponseData::SetPreferenceValue { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::DownloadPlugin { plugin_id } => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.download_plugin(plugin_id.clone())
|
||||
.map(|data| ServerGrpcApiResponseData::DownloadPlugin { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::DownloadStatus {} => {
|
||||
let data = state.application_manager.download_status();
|
||||
|
||||
responder.respond(Ok(ServerGrpcApiResponseData::DownloadStatus { data }));
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::RemovePlugin { plugin_id } => {
|
||||
let result = state
|
||||
.application_manager
|
||||
.remove_plugin(plugin_id.clone())
|
||||
.map(|data| ServerGrpcApiResponseData::RemovePlugin { data });
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ServerGrpcApiRequestData::WaylandGlobalShortcutsEnabled {} => {
|
||||
let result = state.application_manager.config().map(|data| {
|
||||
ServerGrpcApiResponseData::WaylandGlobalShortcutsEnabled {
|
||||
data: data.wayland_use_legacy_x11_api,
|
||||
}
|
||||
});
|
||||
|
||||
responder.respond(result);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ use iced::widget::tooltip;
|
|||
use iced::widget::tooltip::Position;
|
||||
use iced_fonts::bootstrap::exclamation_triangle_fill;
|
||||
|
||||
use crate::theme::Element;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::container::ContainerStyle;
|
||||
use crate::theme::text::TextStyle;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::container::ContainerStyle;
|
||||
use crate::ui::settings::theme::text::TextStyle;
|
||||
|
||||
pub struct ShortcutData {
|
||||
pub shortcut: Option<PhysicalShortcut>,
|
||||
4
rust/client/src/ui/settings/mod.rs
Normal file
4
rust/client/src/ui/settings/mod.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
mod components;
|
||||
pub mod theme;
|
||||
pub mod ui;
|
||||
pub mod views;
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
use iced::theme;
|
||||
use iced::theme::Palette;
|
||||
use iced::theme::Style;
|
||||
|
||||
pub mod button;
|
||||
pub mod checkbox;
|
||||
pub mod container;
|
||||
|
|
@ -14,22 +10,9 @@ pub mod text_input;
|
|||
|
||||
pub type Element<'a, Message> = iced::Element<'a, Message, GauntletSettingsTheme>;
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct GauntletSettingsTheme;
|
||||
|
||||
impl theme::Base for GauntletSettingsTheme {
|
||||
fn base(&self) -> Style {
|
||||
Style {
|
||||
background_color: BACKGROUND_DARKEST.to_iced(),
|
||||
text_color: TEXT_LIGHTEST.to_iced(),
|
||||
}
|
||||
}
|
||||
|
||||
fn palette(&self) -> Option<Palette> {
|
||||
Some(Palette::FERRA)
|
||||
}
|
||||
}
|
||||
|
||||
// keep colors more or less in sync with main ui
|
||||
#[allow(unused)]
|
||||
pub const NOT_INTENDED_TO_BE_USED: ThemeColor = ThemeColor::new(0xAF5BFF, 1.0);
|
||||
|
|
@ -3,16 +3,16 @@ use iced::widget::button;
|
|||
use iced::widget::button::Status;
|
||||
use iced::widget::button::Style;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_LIGHTER;
|
||||
use crate::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::theme::DANGER;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::PRIMARY;
|
||||
use crate::theme::PRIMARY_HOVERED;
|
||||
use crate::theme::SUCCESS;
|
||||
use crate::theme::TEXT_DARKEST;
|
||||
use crate::theme::TEXT_LIGHTEST;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTER;
|
||||
use crate::ui::settings::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::ui::settings::theme::DANGER;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::PRIMARY;
|
||||
use crate::ui::settings::theme::PRIMARY_HOVERED;
|
||||
use crate::ui::settings::theme::SUCCESS;
|
||||
use crate::ui::settings::theme::TEXT_DARKEST;
|
||||
use crate::ui::settings::theme::TEXT_LIGHTEST;
|
||||
|
||||
pub enum ButtonStyle {
|
||||
Primary,
|
||||
|
|
@ -3,12 +3,12 @@ use iced::widget::checkbox;
|
|||
use iced::widget::checkbox::Status;
|
||||
use iced::widget::checkbox::Style;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_DARKEST;
|
||||
use crate::theme::BACKGROUND_LIGHTER;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::PRIMARY;
|
||||
use crate::theme::PRIMARY_HOVERED;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKEST;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTER;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::PRIMARY;
|
||||
use crate::ui::settings::theme::PRIMARY_HOVERED;
|
||||
|
||||
impl checkbox::Catalog for GauntletSettingsTheme {
|
||||
type Class<'a> = ();
|
||||
|
|
@ -1,15 +1,19 @@
|
|||
use iced::Background;
|
||||
use iced::Border;
|
||||
use iced::Color;
|
||||
use iced::widget::container;
|
||||
use iced::widget::container::Style;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_LIGHTER;
|
||||
use crate::theme::DANGER;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::TRANSPARENT;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKEST;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTER;
|
||||
use crate::ui::settings::theme::DANGER;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::TEXT_LIGHTEST;
|
||||
use crate::ui::settings::theme::TRANSPARENT;
|
||||
|
||||
pub enum ContainerStyle {
|
||||
WindowRoot,
|
||||
Transparent,
|
||||
Box,
|
||||
TextInputMissingValue,
|
||||
|
|
@ -60,6 +64,13 @@ impl container::Catalog for GauntletSettingsTheme {
|
|||
..Default::default()
|
||||
}
|
||||
}
|
||||
ContainerStyle::WindowRoot => {
|
||||
Style {
|
||||
background: Some(Background::Color(BACKGROUND_DARKEST.to_iced())),
|
||||
text_color: Some(TEXT_LIGHTEST.to_iced()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@ use iced::Border;
|
|||
use iced::overlay;
|
||||
use iced::widget::pick_list;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_DARKEST;
|
||||
use crate::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::PRIMARY;
|
||||
use crate::theme::PRIMARY_HOVERED;
|
||||
use crate::theme::TEXT_DARKEST;
|
||||
use crate::theme::TEXT_LIGHTEST;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKEST;
|
||||
use crate::ui::settings::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::PRIMARY;
|
||||
use crate::ui::settings::theme::PRIMARY_HOVERED;
|
||||
use crate::ui::settings::theme::TEXT_DARKEST;
|
||||
use crate::ui::settings::theme::TEXT_LIGHTEST;
|
||||
|
||||
impl pick_list::Catalog for GauntletSettingsTheme {
|
||||
type Class<'a> = ();
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use iced::widget::rule;
|
||||
use iced::widget::rule::Style;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
|
||||
impl rule::Catalog for GauntletSettingsTheme {
|
||||
type Class<'a> = ();
|
||||
|
|
@ -6,8 +6,8 @@ use iced::widget::scrollable;
|
|||
use iced::widget::scrollable::Status;
|
||||
use iced::widget::scrollable::Style;
|
||||
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::PRIMARY;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::PRIMARY;
|
||||
|
||||
impl scrollable::Catalog for GauntletSettingsTheme {
|
||||
type Class<'a> = ();
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
use iced::Border;
|
||||
use iced::widget::container::Style;
|
||||
|
||||
use crate::components::shortcut_selector;
|
||||
use crate::components::shortcut_selector::Status;
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_LIGHTER;
|
||||
use crate::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::PRIMARY;
|
||||
use crate::theme::TRANSPARENT;
|
||||
use crate::ui::settings::components::shortcut_selector;
|
||||
use crate::ui::settings::components::shortcut_selector::Status;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTER;
|
||||
use crate::ui::settings::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::PRIMARY;
|
||||
use crate::ui::settings::theme::TRANSPARENT;
|
||||
|
||||
impl shortcut_selector::Catalog for GauntletSettingsTheme {
|
||||
type Class<'a> = ();
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
use iced::widget::text;
|
||||
use iced::widget::text::Style;
|
||||
|
||||
use crate::theme::DANGER_BRIGHT;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::SUCCESS;
|
||||
use crate::theme::TEXT_DARKER;
|
||||
use crate::ui::settings::theme::DANGER_BRIGHT;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::SUCCESS;
|
||||
use crate::ui::settings::theme::TEXT_DARKER;
|
||||
|
||||
pub enum TextStyle {
|
||||
Default,
|
||||
|
|
@ -4,14 +4,14 @@ use iced::widget::text_input;
|
|||
use iced::widget::text_input::Status;
|
||||
use iced::widget::text_input::Style;
|
||||
|
||||
use crate::theme::BACKGROUND_DARKER;
|
||||
use crate::theme::BACKGROUND_LIGHTER;
|
||||
use crate::theme::BACKGROUND_LIGHTEST;
|
||||
use crate::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::TEXT_DARKER;
|
||||
use crate::theme::TEXT_LIGHTEST;
|
||||
use crate::theme::TRANSPARENT;
|
||||
use crate::ui::settings::theme::BACKGROUND_DARKER;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTER;
|
||||
use crate::ui::settings::theme::BACKGROUND_LIGHTEST;
|
||||
use crate::ui::settings::theme::BUTTON_BORDER_RADIUS;
|
||||
use crate::ui::settings::theme::GauntletSettingsTheme;
|
||||
use crate::ui::settings::theme::TEXT_DARKER;
|
||||
use crate::ui::settings::theme::TEXT_LIGHTEST;
|
||||
use crate::ui::settings::theme::TRANSPARENT;
|
||||
|
||||
pub enum TextInputStyle {
|
||||
FormInput,
|
||||
|
|
@ -1,29 +1,23 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use gauntlet_common::model::DownloadStatus;
|
||||
use gauntlet_common::model::EntrypointId;
|
||||
use gauntlet_common::model::PhysicalShortcut;
|
||||
use gauntlet_common::model::PluginId;
|
||||
use gauntlet_common::model::SettingsTheme;
|
||||
use gauntlet_common::model::WindowPositionMode;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApi;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApiProxy;
|
||||
use gauntlet_common::rpc::backend_api::GrpcBackendApi;
|
||||
use gauntlet_common_ui::padding;
|
||||
use gauntlet_server::global_hotkey::GlobalHotKeyManager;
|
||||
use gauntlet_server::plugins::ApplicationManager;
|
||||
use gauntlet_utils::channel::RequestError;
|
||||
use gauntlet_utils::channel::RequestResult;
|
||||
use iced::Alignment;
|
||||
use iced::Length;
|
||||
use iced::Padding;
|
||||
use iced::Renderer;
|
||||
use iced::Size;
|
||||
use iced::Subscription;
|
||||
use iced::Task;
|
||||
use iced::advanced::text::Shaping;
|
||||
use iced::alignment;
|
||||
use iced::font;
|
||||
use iced::futures;
|
||||
use iced::padding;
|
||||
use iced::time;
|
||||
use iced::widget::button;
|
||||
|
|
@ -37,54 +31,73 @@ use iced::widget::scrollable;
|
|||
use iced::widget::stack;
|
||||
use iced::widget::text;
|
||||
use iced::window;
|
||||
use iced_fonts::BOOTSTRAP_FONT_BYTES;
|
||||
use iced_fonts::bootstrap::exclamation_triangle_fill;
|
||||
use iced_fonts::bootstrap::gear_fill;
|
||||
use iced_fonts::bootstrap::patch_check_fill;
|
||||
use iced_fonts::bootstrap::puzzle_fill;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::components::spinner::Spinner;
|
||||
use crate::theme::Element;
|
||||
use crate::theme::GauntletSettingsTheme;
|
||||
use crate::theme::button::ButtonStyle;
|
||||
use crate::theme::container::ContainerStyle;
|
||||
use crate::theme::text::TextStyle;
|
||||
use crate::views::general::ManagementAppGeneralMsgIn;
|
||||
use crate::views::general::ManagementAppGeneralMsgOut;
|
||||
use crate::views::general::ManagementAppGeneralState;
|
||||
use crate::views::plugins::ManagementAppPluginMsgIn;
|
||||
use crate::views::plugins::ManagementAppPluginMsgOut;
|
||||
use crate::views::plugins::ManagementAppPluginsState;
|
||||
use crate::ui::settings::components::spinner::Spinner;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::button::ButtonStyle;
|
||||
use crate::ui::settings::theme::container::ContainerStyle;
|
||||
use crate::ui::settings::theme::text::TextStyle;
|
||||
use crate::ui::settings::views::general::SettingsGeneralMsgIn;
|
||||
use crate::ui::settings::views::general::SettingsGeneralMsgOut;
|
||||
use crate::ui::settings::views::general::SettingsGeneralState;
|
||||
use crate::ui::settings::views::plugins::SelectedItem;
|
||||
use crate::ui::settings::views::plugins::SettingsPluginMsgIn;
|
||||
use crate::ui::settings::views::plugins::SettingsPluginMsgOut;
|
||||
use crate::ui::settings::views::plugins::SettingsPluginsState;
|
||||
|
||||
pub fn run() {
|
||||
iced::application::<ManagementAppModel, ManagementAppMsg, GauntletSettingsTheme, Renderer>(new, update, view)
|
||||
.title("Gauntlet Settings")
|
||||
.window(window::Settings {
|
||||
size: Size::new(1150.0, 700.0),
|
||||
..Default::default()
|
||||
})
|
||||
.subscription(subscription)
|
||||
.theme(|_| GauntletSettingsTheme::default())
|
||||
.run()
|
||||
.expect("Unable to start settings application");
|
||||
}
|
||||
|
||||
struct ManagementAppModel {
|
||||
backend_api: Option<BackendForSettingsApiProxy>,
|
||||
pub struct SettingsWindowState {
|
||||
pub settings_window_id: Option<window::Id>,
|
||||
application_manager: Arc<ApplicationManager>,
|
||||
wayland: bool,
|
||||
error_view: Option<ErrorView>,
|
||||
downloads_info: HashMap<PluginId, DownloadInfo>,
|
||||
download_info_shown: bool,
|
||||
current_settings_view: SettingsView,
|
||||
general_state: ManagementAppGeneralState,
|
||||
plugins_state: ManagementAppPluginsState,
|
||||
general_state: SettingsGeneralState,
|
||||
plugins_state: SettingsPluginsState,
|
||||
}
|
||||
|
||||
impl SettingsWindowState {
|
||||
pub fn new(application_manager: Arc<ApplicationManager>, wayland: bool) -> SettingsWindowState {
|
||||
SettingsWindowState {
|
||||
settings_window_id: None,
|
||||
application_manager: application_manager.clone(),
|
||||
wayland,
|
||||
error_view: None,
|
||||
downloads_info: HashMap::new(),
|
||||
download_info_shown: false,
|
||||
current_settings_view: SettingsView::Plugins,
|
||||
general_state: SettingsGeneralState::new(application_manager.clone()),
|
||||
plugins_state: SettingsPluginsState::new(application_manager.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SettingsParams {
|
||||
Default,
|
||||
PluginPreferences {
|
||||
plugin_id: PluginId,
|
||||
},
|
||||
EntrypointPreferences {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ManagementAppMsg {
|
||||
FontLoaded(Result<(), font::Error>),
|
||||
General(ManagementAppGeneralMsgIn),
|
||||
Plugin(ManagementAppPluginMsgIn),
|
||||
pub enum SettingsMsg {
|
||||
Refresh,
|
||||
OpenSettings(SettingsParams),
|
||||
WindowCreated(window::Id),
|
||||
WindowDestroyed,
|
||||
General(SettingsGeneralMsgIn),
|
||||
Plugin(SettingsPluginMsgIn),
|
||||
SwitchView(SettingsView),
|
||||
DownloadStatus { plugins: HashMap<PluginId, DownloadStatus> },
|
||||
HandleBackendError(RequestError),
|
||||
|
|
@ -113,130 +126,34 @@ pub enum DownloadInfo {
|
|||
Successful,
|
||||
}
|
||||
|
||||
fn new() -> (ManagementAppModel, Task<ManagementAppMsg>) {
|
||||
let backend_api = futures::executor::block_on(async {
|
||||
anyhow::Ok(BackendForSettingsApiProxy::new(GrpcBackendApi::new().await?))
|
||||
})
|
||||
.inspect_err(|err| tracing::error!("Unable to connect to server: {:?}", err))
|
||||
.ok();
|
||||
|
||||
let wayland = if cfg!(target_os = "linux") {
|
||||
std::env::var("WAYLAND_DISPLAY")
|
||||
.or_else(|_| std::env::var("WAYLAND_SOCKET"))
|
||||
.is_ok()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
(
|
||||
ManagementAppModel {
|
||||
backend_api: backend_api.clone(),
|
||||
error_view: None,
|
||||
downloads_info: HashMap::new(),
|
||||
download_info_shown: false,
|
||||
current_settings_view: SettingsView::Plugins,
|
||||
general_state: ManagementAppGeneralState::new(backend_api.clone()),
|
||||
plugins_state: ManagementAppPluginsState::new(backend_api.clone()),
|
||||
},
|
||||
Task::batch([
|
||||
font::load(BOOTSTRAP_FONT_BYTES).map(ManagementAppMsg::FontLoaded),
|
||||
Task::done(ManagementAppMsg::Plugin(ManagementAppPluginMsgIn::FetchPlugins)),
|
||||
Task::future(async {
|
||||
match backend_api {
|
||||
Some(backend_api) => Some(init_data(backend_api).await),
|
||||
None => None,
|
||||
}
|
||||
})
|
||||
.then(move |init_data| {
|
||||
match init_data {
|
||||
None => Task::done(ManagementAppMsg::General(ManagementAppGeneralMsgIn::Noop)),
|
||||
Some(init) => {
|
||||
match init {
|
||||
Ok(init) => {
|
||||
Task::batch([
|
||||
Task::done(ManagementAppMsg::General(ManagementAppGeneralMsgIn::InitSetting {
|
||||
theme: init.theme,
|
||||
window_position_mode: init.window_position_mode,
|
||||
shortcut: init.global_shortcut,
|
||||
shortcut_error: init.global_shortcut_error,
|
||||
global_shortcuts_unsupported: wayland && !init.wayland_global_shortcuts_enabled,
|
||||
})),
|
||||
Task::done(ManagementAppMsg::Plugin(ManagementAppPluginMsgIn::InitSetting {
|
||||
global_entrypoint_shortcuts: init.global_entrypoint_shortcuts,
|
||||
show_global_shortcuts: !wayland || init.wayland_global_shortcuts_enabled,
|
||||
})),
|
||||
])
|
||||
}
|
||||
Err(err) => Task::done(ManagementAppMsg::HandleBackendError(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
struct InitSettingsData {
|
||||
global_shortcut: Option<PhysicalShortcut>,
|
||||
global_shortcut_error: Option<String>,
|
||||
theme: SettingsTheme,
|
||||
window_position_mode: WindowPositionMode,
|
||||
global_entrypoint_shortcuts: HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>,
|
||||
wayland_global_shortcuts_enabled: bool,
|
||||
}
|
||||
|
||||
async fn init_data(backend_api: impl BackendForSettingsApi) -> RequestResult<InitSettingsData> {
|
||||
let (global_shortcut, global_shortcut_error) = backend_api.get_global_shortcut().await?;
|
||||
let global_entrypoint_shortcuts = backend_api.get_global_entrypoint_shortcuts().await?;
|
||||
|
||||
let theme = backend_api.get_theme().await?;
|
||||
|
||||
let window_position_mode = backend_api.get_window_position_mode().await?;
|
||||
let wayland_global_shortcuts_enabled = backend_api.wayland_global_shortcuts_enabled().await?;
|
||||
|
||||
Ok(InitSettingsData {
|
||||
global_shortcut,
|
||||
global_shortcut_error,
|
||||
global_entrypoint_shortcuts,
|
||||
theme,
|
||||
window_position_mode,
|
||||
wayland_global_shortcuts_enabled,
|
||||
})
|
||||
}
|
||||
|
||||
fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<ManagementAppMsg> {
|
||||
let backend_api = match &state.backend_api {
|
||||
Some(backend_api) => backend_api.clone(),
|
||||
None => return Task::none(),
|
||||
};
|
||||
|
||||
pub fn update_settings(
|
||||
state: &mut SettingsWindowState,
|
||||
global_hotkey_manager: &Option<GlobalHotKeyManager>,
|
||||
message: SettingsMsg,
|
||||
) -> Task<SettingsMsg> {
|
||||
match message {
|
||||
ManagementAppMsg::Plugin(message) => {
|
||||
state.plugins_state.update(message).map(|msg| {
|
||||
SettingsMsg::Plugin(message) => {
|
||||
state.plugins_state.update(global_hotkey_manager, message).map(|msg| {
|
||||
match msg {
|
||||
ManagementAppPluginMsgOut::Inner(msg) => ManagementAppMsg::Plugin(msg),
|
||||
ManagementAppPluginMsgOut::Outer(msg) => msg,
|
||||
SettingsPluginMsgOut::Inner(msg) => SettingsMsg::Plugin(msg),
|
||||
SettingsPluginMsgOut::Outer(msg) => msg,
|
||||
}
|
||||
})
|
||||
}
|
||||
ManagementAppMsg::General(message) => {
|
||||
state.general_state.update(message).map(|msg| {
|
||||
SettingsMsg::General(message) => {
|
||||
state.general_state.update(global_hotkey_manager, message).map(|msg| {
|
||||
match msg {
|
||||
ManagementAppGeneralMsgOut::Inner(msg) => ManagementAppMsg::General(msg),
|
||||
ManagementAppGeneralMsgOut::Outer(msg) => msg,
|
||||
SettingsGeneralMsgOut::Inner(msg) => SettingsMsg::General(msg),
|
||||
SettingsGeneralMsgOut::Outer(msg) => msg,
|
||||
}
|
||||
})
|
||||
}
|
||||
ManagementAppMsg::FontLoaded(result) => {
|
||||
result.expect("unable to load font");
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppMsg::SwitchView(view) => {
|
||||
SettingsMsg::SwitchView(view) => {
|
||||
state.current_settings_view = view;
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppMsg::HandleBackendError(err) => {
|
||||
SettingsMsg::HandleBackendError(err) => {
|
||||
state.error_view = Some(match err {
|
||||
RequestError::Timeout => ErrorView::Timeout,
|
||||
RequestError::Other { display } => ErrorView::UnknownError { display },
|
||||
|
|
@ -249,7 +166,7 @@ fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<Man
|
|||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppMsg::DownloadStatus { plugins } => {
|
||||
SettingsMsg::DownloadStatus { plugins } => {
|
||||
for (plugin, status) in plugins {
|
||||
match status {
|
||||
DownloadStatus::InProgress => {
|
||||
|
|
@ -266,13 +183,13 @@ fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<Man
|
|||
}
|
||||
}
|
||||
|
||||
let backend_api = backend_api.clone();
|
||||
let application_manager = state.application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
let plugins = backend_api.plugins().await?;
|
||||
let global_entrypoint_shortcuts = backend_api.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_search_aliases = backend_api.get_entrypoint_search_aliases().await?;
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts = application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_search_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_search_aliases))
|
||||
},
|
||||
|
|
@ -280,7 +197,7 @@ fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<Man
|
|||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_search_aliases)| {
|
||||
ManagementAppMsg::Plugin(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
SettingsMsg::Plugin(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_search_aliases,
|
||||
|
|
@ -290,24 +207,17 @@ fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<Man
|
|||
},
|
||||
)
|
||||
}
|
||||
ManagementAppMsg::CheckDownloadStatus => {
|
||||
SettingsMsg::CheckDownloadStatus => {
|
||||
if state.downloads_info.is_empty() {
|
||||
Task::none()
|
||||
} else {
|
||||
let backend_client = backend_api.clone();
|
||||
let plugins = state.application_manager.download_status();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
let plugins = backend_client.download_status().await?;
|
||||
|
||||
Ok(plugins)
|
||||
},
|
||||
|result| handle_backend_error(result, |plugins| ManagementAppMsg::DownloadStatus { plugins }),
|
||||
)
|
||||
Task::done(SettingsMsg::DownloadStatus { plugins })
|
||||
}
|
||||
}
|
||||
ManagementAppMsg::DownloadPlugin { plugin_id } => {
|
||||
let backend_client = backend_api.clone();
|
||||
SettingsMsg::DownloadPlugin { plugin_id } => {
|
||||
let backend_client = state.application_manager.clone();
|
||||
|
||||
let already_downloading = state
|
||||
.downloads_info
|
||||
|
|
@ -317,39 +227,97 @@ fn update(state: &mut ManagementAppModel, message: ManagementAppMsg) -> Task<Man
|
|||
if already_downloading {
|
||||
Task::none()
|
||||
} else {
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client.download_plugin(plugin_id).await?;
|
||||
backend_client.download_plugin(plugin_id);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|result| handle_backend_error(result, |()| ManagementAppMsg::Noop),
|
||||
)
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
ManagementAppMsg::Noop => Task::none(),
|
||||
ManagementAppMsg::ToggleDownloadInfo => {
|
||||
SettingsMsg::Noop => Task::none(),
|
||||
SettingsMsg::ToggleDownloadInfo => {
|
||||
state.download_info_shown = !state.download_info_shown;
|
||||
Task::none()
|
||||
}
|
||||
SettingsMsg::Refresh => {
|
||||
fn run(state: &mut SettingsWindowState) -> anyhow::Result<Task<SettingsMsg>> {
|
||||
let (global_shortcut, global_shortcut_error) =
|
||||
state.application_manager.get_global_shortcut().map(|data| {
|
||||
data.map(|(shortcut, error)| (Some(shortcut), error))
|
||||
.unwrap_or((None, None))
|
||||
})?;
|
||||
|
||||
let global_entrypoint_shortcuts = state.application_manager.get_global_entrypoint_shortcuts()?;
|
||||
|
||||
let theme = state.application_manager.get_theme()?;
|
||||
|
||||
let window_position_mode = state.application_manager.get_window_position_mode()?;
|
||||
let wayland_global_shortcuts_enabled = state.application_manager.config()?.wayland_use_legacy_x11_api;
|
||||
|
||||
Ok(Task::batch([
|
||||
Task::done(SettingsMsg::General(SettingsGeneralMsgIn::InitSetting {
|
||||
theme,
|
||||
window_position_mode,
|
||||
shortcut: global_shortcut,
|
||||
shortcut_error: global_shortcut_error,
|
||||
global_shortcuts_unsupported: state.wayland && !wayland_global_shortcuts_enabled,
|
||||
})),
|
||||
Task::done(SettingsMsg::Plugin(SettingsPluginMsgIn::InitSetting {
|
||||
global_entrypoint_shortcuts,
|
||||
show_global_shortcuts: !state.wayland || wayland_global_shortcuts_enabled,
|
||||
})),
|
||||
]))
|
||||
}
|
||||
|
||||
run(state).unwrap_or_else(|err| Task::done(SettingsMsg::HandleBackendError(err.into())))
|
||||
}
|
||||
SettingsMsg::WindowCreated(window_id) => {
|
||||
state.settings_window_id = Some(window_id);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
SettingsMsg::WindowDestroyed => {
|
||||
state.settings_window_id = None;
|
||||
|
||||
Task::none()
|
||||
}
|
||||
SettingsMsg::OpenSettings(settings_params) => {
|
||||
let item = match settings_params {
|
||||
SettingsParams::Default => SelectedItem::None,
|
||||
SettingsParams::PluginPreferences { plugin_id } => SelectedItem::Plugin { plugin_id },
|
||||
SettingsParams::EntrypointPreferences {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
SelectedItem::Entrypoint {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let open = match state.settings_window_id {
|
||||
None => {
|
||||
let settings = window::Settings {
|
||||
size: Size::new(1150.0, 700.0),
|
||||
..Default::default()
|
||||
};
|
||||
let (_, open) = window::open(settings);
|
||||
open.map(SettingsMsg::WindowCreated)
|
||||
}
|
||||
Some(window_id) => window::gain_focus(window_id),
|
||||
};
|
||||
|
||||
Task::batch([
|
||||
open,
|
||||
Task::done(SettingsMsg::Plugin(SettingsPluginMsgIn::FetchPlugins)),
|
||||
Task::done(SettingsMsg::Refresh),
|
||||
Task::done(SettingsMsg::SwitchView(SettingsView::Plugins)),
|
||||
Task::done(SettingsMsg::Plugin(SettingsPluginMsgIn::SelectItem(item))),
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
||||
if let None = &state.backend_api {
|
||||
let description: Element<_> =
|
||||
text("Unable to connect to server. Please check if you have Gauntlet running on your PC").into();
|
||||
|
||||
let content: Element<_> = container(description)
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into();
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
pub fn view_settings(state: &SettingsWindowState) -> Element<'_, SettingsMsg> {
|
||||
if let Some(err) = &state.error_view {
|
||||
return match err {
|
||||
ErrorView::Timeout => {
|
||||
|
|
@ -421,8 +389,8 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
}
|
||||
|
||||
let content = match state.current_settings_view {
|
||||
SettingsView::General => state.general_state.view().map(|msg| ManagementAppMsg::General(msg)),
|
||||
SettingsView::Plugins => state.plugins_state.view().map(|msg| ManagementAppMsg::Plugin(msg)),
|
||||
SettingsView::General => state.general_state.view().map(|msg| SettingsMsg::General(msg)),
|
||||
SettingsView::Plugins => state.plugins_state.view().map(|msg| SettingsMsg::Plugin(msg)),
|
||||
};
|
||||
|
||||
let icon_general: Element<_> = gear_fill()
|
||||
|
|
@ -445,7 +413,7 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
.into();
|
||||
|
||||
let general_button: Element<_> = button(general_button)
|
||||
.on_press(ManagementAppMsg::SwitchView(SettingsView::General))
|
||||
.on_press(SettingsMsg::SwitchView(SettingsView::General))
|
||||
.height(Length::Fill)
|
||||
.width(80)
|
||||
.class(
|
||||
|
|
@ -479,7 +447,7 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
.into();
|
||||
|
||||
let plugins_button: Element<_> = button(plugins_button)
|
||||
.on_press(ManagementAppMsg::SwitchView(SettingsView::Plugins))
|
||||
.on_press(SettingsMsg::SwitchView(SettingsView::Plugins))
|
||||
.height(Length::Fill)
|
||||
.width(80)
|
||||
.class(
|
||||
|
|
@ -587,7 +555,7 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
|
||||
let top_bar_right: Element<_> = button(top_bar_right)
|
||||
.class(ButtonStyle::DownloadInfo)
|
||||
.on_press(ManagementAppMsg::ToggleDownloadInfo)
|
||||
.on_press(SettingsMsg::ToggleDownloadInfo)
|
||||
.padding(Padding::from([4, 8]))
|
||||
.height(Length::Fill)
|
||||
.into();
|
||||
|
|
@ -735,12 +703,17 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
.into()
|
||||
};
|
||||
|
||||
let content = container(content)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.class(ContainerStyle::WindowRoot);
|
||||
|
||||
let content: Element<_> = mouse_area(content)
|
||||
.on_press(
|
||||
if state.download_info_shown {
|
||||
ManagementAppMsg::ToggleDownloadInfo
|
||||
SettingsMsg::ToggleDownloadInfo
|
||||
} else {
|
||||
ManagementAppMsg::Noop
|
||||
SettingsMsg::Noop
|
||||
},
|
||||
)
|
||||
.into();
|
||||
|
|
@ -754,16 +727,16 @@ fn view(state: &ManagementAppModel) -> Element<'_, ManagementAppMsg> {
|
|||
stack(content).into()
|
||||
}
|
||||
|
||||
fn subscription(_state: &ManagementAppModel) -> Subscription<ManagementAppMsg> {
|
||||
time::every(Duration::from_millis(300)).map(|_| ManagementAppMsg::CheckDownloadStatus)
|
||||
}
|
||||
|
||||
pub fn handle_backend_error<T>(
|
||||
result: RequestResult<T>,
|
||||
convert: impl FnOnce(T) -> ManagementAppMsg,
|
||||
) -> ManagementAppMsg {
|
||||
match result {
|
||||
Ok(val) => convert(val),
|
||||
Err(err) => ManagementAppMsg::HandleBackendError(err),
|
||||
pub fn subscription_settings(state: &SettingsWindowState) -> Subscription<SettingsMsg> {
|
||||
match state.settings_window_id {
|
||||
None => Subscription::none(),
|
||||
Some(_) => time::every(Duration::from_millis(300)).map(|_| SettingsMsg::CheckDownloadStatus),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_backend_error<T>(result: RequestResult<T>, convert: impl FnOnce(T) -> SettingsMsg) -> SettingsMsg {
|
||||
match result {
|
||||
Ok(val) => convert(val),
|
||||
Err(err) => SettingsMsg::HandleBackendError(err),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use gauntlet_common::model::PhysicalShortcut;
|
||||
use gauntlet_common::model::SettingsTheme;
|
||||
use gauntlet_common::model::WindowPositionMode;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApi;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApiProxy;
|
||||
use gauntlet_server::global_hotkey::GlobalHotKeyManager;
|
||||
use gauntlet_server::plugins::ApplicationManager;
|
||||
use gauntlet_utils::channel::RequestResult;
|
||||
use iced::Alignment;
|
||||
use iced::Font;
|
||||
|
|
@ -20,15 +22,15 @@ use iced::widget::row;
|
|||
use iced::widget::text;
|
||||
use iced::widget::text::Shaping;
|
||||
|
||||
use crate::components::shortcut_selector::ShortcutData;
|
||||
use crate::components::shortcut_selector::render_shortcut_error;
|
||||
use crate::components::shortcut_selector::shortcut_selector;
|
||||
use crate::theme::Element;
|
||||
use crate::theme::container::ContainerStyle;
|
||||
use crate::ui::ManagementAppMsg;
|
||||
use crate::ui::settings::components::shortcut_selector::ShortcutData;
|
||||
use crate::ui::settings::components::shortcut_selector::render_shortcut_error;
|
||||
use crate::ui::settings::components::shortcut_selector::shortcut_selector;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::container::ContainerStyle;
|
||||
use crate::ui::settings::ui::SettingsMsg;
|
||||
|
||||
pub struct ManagementAppGeneralState {
|
||||
backend_api: Option<BackendForSettingsApiProxy>,
|
||||
pub struct SettingsGeneralState {
|
||||
application_manager: Arc<ApplicationManager>,
|
||||
theme: SettingsTheme,
|
||||
window_position_mode: WindowPositionMode,
|
||||
current_shortcut: ShortcutData,
|
||||
|
|
@ -36,7 +38,7 @@ pub struct ManagementAppGeneralState {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ManagementAppGeneralMsgIn {
|
||||
pub enum SettingsGeneralMsgIn {
|
||||
ShortcutCaptured(Option<PhysicalShortcut>),
|
||||
ThemeChanged(SettingsTheme),
|
||||
WindowPositionModeChanged(WindowPositionMode),
|
||||
|
|
@ -51,19 +53,18 @@ pub enum ManagementAppGeneralMsgIn {
|
|||
shortcut_error: Option<String>,
|
||||
global_shortcuts_unsupported: bool,
|
||||
},
|
||||
Noop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ManagementAppGeneralMsgOut {
|
||||
Inner(ManagementAppGeneralMsgIn),
|
||||
Outer(ManagementAppMsg),
|
||||
pub enum SettingsGeneralMsgOut {
|
||||
Inner(SettingsGeneralMsgIn),
|
||||
Outer(SettingsMsg),
|
||||
}
|
||||
|
||||
impl ManagementAppGeneralState {
|
||||
pub fn new(backend_api: Option<BackendForSettingsApiProxy>) -> Self {
|
||||
impl SettingsGeneralState {
|
||||
pub fn new(application_manager: Arc<ApplicationManager>) -> Self {
|
||||
Self {
|
||||
backend_api,
|
||||
application_manager,
|
||||
theme: SettingsTheme::AutoDetect,
|
||||
window_position_mode: WindowPositionMode::Static,
|
||||
current_shortcut: ShortcutData {
|
||||
|
|
@ -74,40 +75,29 @@ impl ManagementAppGeneralState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: ManagementAppGeneralMsgIn) -> Task<ManagementAppGeneralMsgOut> {
|
||||
let backend_api = match &self.backend_api {
|
||||
Some(backend_api) => backend_api.clone(),
|
||||
None => return Task::none(),
|
||||
};
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
global_hotkey_manager: &Option<GlobalHotKeyManager>,
|
||||
message: SettingsGeneralMsgIn,
|
||||
) -> Task<SettingsGeneralMsgOut> {
|
||||
match message {
|
||||
ManagementAppGeneralMsgIn::ShortcutCaptured(shortcut) => {
|
||||
let backend_api = backend_api.clone();
|
||||
SettingsGeneralMsgIn::ShortcutCaptured(shortcut) => {
|
||||
let Some(global_hotkey_manager) = &global_hotkey_manager else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
Task::perform(
|
||||
{
|
||||
let shortcut = shortcut.clone();
|
||||
let error = self
|
||||
.application_manager
|
||||
.set_global_shortcut(global_hotkey_manager, shortcut.clone());
|
||||
|
||||
async move {
|
||||
let error = backend_api.set_global_shortcut(shortcut).await?;
|
||||
|
||||
Ok(error)
|
||||
}
|
||||
Task::done(SettingsGeneralMsgOut::Inner(
|
||||
SettingsGeneralMsgIn::HandleShortcutResponse {
|
||||
shortcut,
|
||||
shortcut_error: error,
|
||||
},
|
||||
move |result| {
|
||||
let shortcut = shortcut.clone();
|
||||
|
||||
handle_backend_error(result, move |shortcut_error| {
|
||||
ManagementAppGeneralMsgOut::Inner(ManagementAppGeneralMsgIn::HandleShortcutResponse {
|
||||
shortcut,
|
||||
shortcut_error,
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
))
|
||||
}
|
||||
ManagementAppGeneralMsgIn::Noop => Task::none(),
|
||||
ManagementAppGeneralMsgIn::InitSetting {
|
||||
SettingsGeneralMsgIn::InitSetting {
|
||||
theme,
|
||||
window_position_mode,
|
||||
shortcut,
|
||||
|
|
@ -124,39 +114,35 @@ impl ManagementAppGeneralState {
|
|||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppGeneralMsgIn::ThemeChanged(theme) => {
|
||||
SettingsGeneralMsgIn::ThemeChanged(theme) => {
|
||||
self.theme = theme.clone();
|
||||
|
||||
let backend_api = backend_api.clone();
|
||||
let application_manager = self.application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_api.set_theme(theme).await?;
|
||||
application_manager.set_theme(theme).await?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(result, |()| ManagementAppGeneralMsgOut::Outer(ManagementAppMsg::Noop))
|
||||
},
|
||||
|result| handle_backend_error(result, |()| SettingsGeneralMsgOut::Outer(SettingsMsg::Noop)),
|
||||
)
|
||||
}
|
||||
ManagementAppGeneralMsgIn::WindowPositionModeChanged(mode) => {
|
||||
SettingsGeneralMsgIn::WindowPositionModeChanged(mode) => {
|
||||
self.window_position_mode = mode.clone();
|
||||
|
||||
let backend_api = backend_api.clone();
|
||||
let application_manager = self.application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_api.set_window_position_mode(mode).await?;
|
||||
application_manager.set_window_position_mode(mode).await?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(result, |()| ManagementAppGeneralMsgOut::Outer(ManagementAppMsg::Noop))
|
||||
},
|
||||
|result| handle_backend_error(result, |()| SettingsGeneralMsgOut::Outer(SettingsMsg::Noop)),
|
||||
)
|
||||
}
|
||||
ManagementAppGeneralMsgIn::HandleShortcutResponse {
|
||||
SettingsGeneralMsgIn::HandleShortcutResponse {
|
||||
shortcut,
|
||||
shortcut_error,
|
||||
} => {
|
||||
|
|
@ -170,7 +156,7 @@ impl ManagementAppGeneralState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn view(&self) -> Element<ManagementAppGeneralMsgIn> {
|
||||
pub fn view(&self) -> Element<SettingsGeneralMsgIn> {
|
||||
let global_shortcut_selector: Element<_> = if self.global_shortcuts_unsupported {
|
||||
let text = text("Not supported").font(Font {
|
||||
style: Style::Italic,
|
||||
|
|
@ -186,7 +172,7 @@ impl ManagementAppGeneralState {
|
|||
} else {
|
||||
shortcut_selector(
|
||||
&self.current_shortcut,
|
||||
move |shortcut| ManagementAppGeneralMsgIn::ShortcutCaptured(shortcut),
|
||||
move |shortcut| SettingsGeneralMsgIn::ShortcutCaptured(shortcut),
|
||||
ContainerStyle::Box,
|
||||
false,
|
||||
)
|
||||
|
|
@ -221,7 +207,7 @@ impl ManagementAppGeneralState {
|
|||
content
|
||||
}
|
||||
|
||||
fn theme_field(&self) -> Element<ManagementAppGeneralMsgIn> {
|
||||
fn theme_field(&self) -> Element<SettingsGeneralMsgIn> {
|
||||
let theme_field = match &self.theme {
|
||||
SettingsTheme::ThemeFile => {
|
||||
let theme_field: Element<_> = text("Unable to change because theme config file is present ")
|
||||
|
|
@ -250,7 +236,7 @@ impl ManagementAppGeneralState {
|
|||
];
|
||||
|
||||
let theme_field: Element<_> = pick_list(theme_items, Some(self.theme.clone()), move |item| {
|
||||
ManagementAppGeneralMsgIn::ThemeChanged(item)
|
||||
SettingsGeneralMsgIn::ThemeChanged(item)
|
||||
})
|
||||
.into();
|
||||
|
||||
|
|
@ -266,11 +252,11 @@ impl ManagementAppGeneralState {
|
|||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn window_position_mode_field(&self) -> Element<ManagementAppGeneralMsgIn> {
|
||||
fn window_position_mode_field(&self) -> Element<SettingsGeneralMsgIn> {
|
||||
let items = [WindowPositionMode::Static, WindowPositionMode::ActiveMonitor];
|
||||
|
||||
let field: Element<_> = pick_list(items, Some(self.window_position_mode.clone()), move |item| {
|
||||
ManagementAppGeneralMsgIn::WindowPositionModeChanged(item)
|
||||
SettingsGeneralMsgIn::WindowPositionModeChanged(item)
|
||||
})
|
||||
.into();
|
||||
|
||||
|
|
@ -284,9 +270,9 @@ impl ManagementAppGeneralState {
|
|||
fn view_field<'a>(
|
||||
&'a self,
|
||||
label: &'a str,
|
||||
input: Element<'a, ManagementAppGeneralMsgIn>,
|
||||
after: Option<Element<'a, ManagementAppGeneralMsgIn>>,
|
||||
) -> Element<'a, ManagementAppGeneralMsgIn> {
|
||||
input: Element<'a, SettingsGeneralMsgIn>,
|
||||
after: Option<Element<'a, SettingsGeneralMsgIn>>,
|
||||
) -> Element<'a, SettingsGeneralMsgIn> {
|
||||
let label: Element<_> = text(label)
|
||||
.shaping(Shaping::Advanced)
|
||||
.align_x(Horizontal::Right)
|
||||
|
|
@ -306,7 +292,7 @@ impl ManagementAppGeneralState {
|
|||
row
|
||||
}
|
||||
|
||||
fn shortcut_capture_after(&self) -> Element<ManagementAppGeneralMsgIn> {
|
||||
fn shortcut_capture_after(&self) -> Element<SettingsGeneralMsgIn> {
|
||||
if let Some(current_shortcut_error) = &self.current_shortcut.error {
|
||||
let content = render_shortcut_error(current_shortcut_error.clone());
|
||||
|
||||
|
|
@ -325,10 +311,10 @@ impl ManagementAppGeneralState {
|
|||
|
||||
fn handle_backend_error<T>(
|
||||
result: RequestResult<T>,
|
||||
convert: impl FnOnce(T) -> ManagementAppGeneralMsgOut,
|
||||
) -> ManagementAppGeneralMsgOut {
|
||||
convert: impl FnOnce(T) -> SettingsGeneralMsgOut,
|
||||
) -> SettingsGeneralMsgOut {
|
||||
match result {
|
||||
Ok(val) => convert(val),
|
||||
Err(err) => ManagementAppGeneralMsgOut::Outer(ManagementAppMsg::HandleBackendError(err)),
|
||||
Err(err) => SettingsGeneralMsgOut::Outer(SettingsMsg::HandleBackendError(err)),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use gauntlet_common::SETTINGS_ENV;
|
||||
use gauntlet_common::SettingsEnvData;
|
||||
use gauntlet_common::model::EntrypointId;
|
||||
use gauntlet_common::model::PhysicalShortcut;
|
||||
use gauntlet_common::model::PluginId;
|
||||
use gauntlet_common::model::PluginPreferenceUserData;
|
||||
use gauntlet_common::model::SettingsEntrypointType;
|
||||
use gauntlet_common::model::SettingsPlugin;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApi;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApiProxy;
|
||||
use gauntlet_common::settings_env_data_from_string;
|
||||
use gauntlet_server::global_hotkey::GlobalHotKeyManager;
|
||||
use gauntlet_server::plugins::ApplicationManager;
|
||||
use gauntlet_utils::channel::RequestResult;
|
||||
use iced::Alignment;
|
||||
use iced::Length;
|
||||
|
|
@ -30,22 +28,22 @@ use iced::widget::text_input;
|
|||
use iced::widget::vertical_rule;
|
||||
use iced_fonts::bootstrap::plus;
|
||||
|
||||
use crate::theme::Element;
|
||||
use crate::theme::button::ButtonStyle;
|
||||
use crate::theme::text::TextStyle;
|
||||
use crate::ui::ManagementAppMsg;
|
||||
use crate::views::plugins::preferences::PluginPreferencesMsg;
|
||||
use crate::views::plugins::preferences::SelectItem;
|
||||
use crate::views::plugins::preferences::preferences_ui;
|
||||
use crate::views::plugins::table::PluginTableMsgIn;
|
||||
use crate::views::plugins::table::PluginTableMsgOut;
|
||||
use crate::views::plugins::table::PluginTableState;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::button::ButtonStyle;
|
||||
use crate::ui::settings::theme::text::TextStyle;
|
||||
use crate::ui::settings::ui::SettingsMsg;
|
||||
use crate::ui::settings::views::plugins::preferences::PluginPreferencesMsg;
|
||||
use crate::ui::settings::views::plugins::preferences::SelectItem;
|
||||
use crate::ui::settings::views::plugins::preferences::preferences_ui;
|
||||
use crate::ui::settings::views::plugins::table::PluginTableMsgIn;
|
||||
use crate::ui::settings::views::plugins::table::PluginTableMsgOut;
|
||||
use crate::ui::settings::views::plugins::table::PluginTableState;
|
||||
|
||||
mod preferences;
|
||||
mod table;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ManagementAppPluginMsgIn {
|
||||
pub enum SettingsPluginMsgIn {
|
||||
InitSetting {
|
||||
global_entrypoint_shortcuts: HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>,
|
||||
show_global_shortcuts: bool,
|
||||
|
|
@ -74,13 +72,13 @@ pub enum ManagementAppPluginMsgIn {
|
|||
SelectItem(SelectedItem),
|
||||
}
|
||||
|
||||
pub enum ManagementAppPluginMsgOut {
|
||||
Inner(ManagementAppPluginMsgIn),
|
||||
Outer(ManagementAppMsg),
|
||||
pub enum SettingsPluginMsgOut {
|
||||
Inner(SettingsPluginMsgIn),
|
||||
Outer(SettingsMsg),
|
||||
}
|
||||
|
||||
pub struct ManagementAppPluginsState {
|
||||
backend_api: Option<BackendForSettingsApiProxy>,
|
||||
pub struct SettingsPluginsState {
|
||||
application_manager: Arc<ApplicationManager>,
|
||||
table_state: PluginTableState,
|
||||
plugin_data: Rc<RefCell<PluginDataContainer>>,
|
||||
preference_user_data: HashMap<(PluginId, Option<EntrypointId>, String), PluginPreferenceUserDataState>,
|
||||
|
|
@ -89,52 +87,27 @@ pub struct ManagementAppPluginsState {
|
|||
entrypoint_search_aliases: HashMap<(PluginId, EntrypointId), String>,
|
||||
}
|
||||
|
||||
impl ManagementAppPluginsState {
|
||||
pub fn new(backend_api: Option<BackendForSettingsApiProxy>) -> Self {
|
||||
let settings_env_data = std::env::var(SETTINGS_ENV)
|
||||
.ok()
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(|val| settings_env_data_from_string(val));
|
||||
|
||||
let select_item = match settings_env_data {
|
||||
None => SelectedItem::None,
|
||||
Some(SettingsEnvData::OpenEntrypointPreferences {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
}) => {
|
||||
SelectedItem::Entrypoint {
|
||||
plugin_id: PluginId::from_string(plugin_id),
|
||||
entrypoint_id: EntrypointId::from_string(entrypoint_id),
|
||||
}
|
||||
}
|
||||
Some(SettingsEnvData::OpenPluginPreferences { plugin_id }) => {
|
||||
SelectedItem::Plugin {
|
||||
plugin_id: PluginId::from_string(plugin_id),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tracing::debug!("Opening selected item: {:?}", select_item);
|
||||
|
||||
impl SettingsPluginsState {
|
||||
pub fn new(application_manager: Arc<ApplicationManager>) -> Self {
|
||||
Self {
|
||||
backend_api: backend_api.clone(),
|
||||
application_manager: application_manager.clone(),
|
||||
plugin_data: Rc::new(RefCell::new(PluginDataContainer::new())),
|
||||
preference_user_data: HashMap::new(),
|
||||
selected_item: select_item,
|
||||
selected_item: SelectedItem::None,
|
||||
table_state: PluginTableState::new(),
|
||||
global_entrypoint_shortcuts: HashMap::new(),
|
||||
entrypoint_search_aliases: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: ManagementAppPluginMsgIn) -> Task<ManagementAppPluginMsgOut> {
|
||||
let backend_api = match &self.backend_api {
|
||||
Some(backend_api) => backend_api.clone(),
|
||||
None => return Task::none(),
|
||||
};
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
global_hotkey_manager: &Option<GlobalHotKeyManager>,
|
||||
message: SettingsPluginMsgIn,
|
||||
) -> Task<SettingsPluginMsgOut> {
|
||||
let application_manager = self.application_manager.clone();
|
||||
match message {
|
||||
ManagementAppPluginMsgIn::InitSetting {
|
||||
SettingsPluginMsgIn::InitSetting {
|
||||
global_entrypoint_shortcuts,
|
||||
show_global_shortcuts,
|
||||
} => {
|
||||
|
|
@ -143,156 +116,162 @@ impl ManagementAppPluginsState {
|
|||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppPluginMsgIn::PluginTableMsg(message) => {
|
||||
self.table_state.update(message).then(move |msg| {
|
||||
match msg {
|
||||
PluginTableMsgOut::SetPluginState { enabled, plugin_id } => {
|
||||
let backend_client = backend_api.clone();
|
||||
SettingsPluginMsgIn::PluginTableMsg(message) => {
|
||||
let application_manager = application_manager.clone();
|
||||
match self.table_state.update(message) {
|
||||
PluginTableMsgOut::SetPluginState { enabled, plugin_id } => {
|
||||
let application_manager = application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client.set_plugin_state(plugin_id, enabled).await?;
|
||||
Task::perform(
|
||||
async move {
|
||||
application_manager.set_plugin_state(plugin_id, enabled)?;
|
||||
|
||||
let plugins = backend_client.plugins().await?;
|
||||
let global_entrypoint_shortcuts =
|
||||
backend_client.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_client.get_entrypoint_search_aliases().await?;
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts =
|
||||
application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
PluginTableMsgOut::SetEntrypointState {
|
||||
enabled,
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
PluginTableMsgOut::SetEntrypointState {
|
||||
enabled,
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
let application_manager = application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
application_manager.set_entrypoint_state(plugin_id, entrypoint_id, enabled)?;
|
||||
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts =
|
||||
application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
PluginTableMsgOut::SelectItem(selected_item) => {
|
||||
Task::done(SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::SelectItem(
|
||||
selected_item,
|
||||
)))
|
||||
}
|
||||
PluginTableMsgOut::ToggleShowEntrypoints { plugin_id } => {
|
||||
Task::done(SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::ToggleShowEntrypoint {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
let backend_client = backend_api.clone();
|
||||
}))
|
||||
}
|
||||
PluginTableMsgOut::ToggleShowGeneratedEntrypoints {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
Task::done(SettingsPluginMsgOut::Inner(
|
||||
SettingsPluginMsgIn::ToggleShowGeneratedEntrypoint {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
},
|
||||
))
|
||||
}
|
||||
PluginTableMsgOut::ShortcutCaptured(plugin_id, entrypoint_id, shortcut) => {
|
||||
let Some(global_hotkey_manager) = &global_hotkey_manager else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client
|
||||
.set_entrypoint_state(plugin_id, entrypoint_id, enabled)
|
||||
.await?;
|
||||
fn run(
|
||||
application_manager: &ApplicationManager,
|
||||
global_hotkey_manager: &GlobalHotKeyManager,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
shortcut: Option<PhysicalShortcut>,
|
||||
) -> anyhow::Result<SettingsPluginMsgOut> {
|
||||
application_manager.set_global_entrypoint_shortcut(
|
||||
global_hotkey_manager,
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
shortcut,
|
||||
)?;
|
||||
|
||||
let plugins = backend_client.plugins().await?;
|
||||
let global_entrypoint_shortcuts =
|
||||
backend_client.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_client.get_entrypoint_search_aliases().await?;
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts = application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
PluginTableMsgOut::SelectItem(selected_item) => {
|
||||
Task::done(ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::SelectItem(
|
||||
selected_item,
|
||||
Ok(SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
)))
|
||||
}
|
||||
PluginTableMsgOut::ToggleShowEntrypoints { plugin_id } => {
|
||||
Task::done(ManagementAppPluginMsgOut::Inner(
|
||||
ManagementAppPluginMsgIn::ToggleShowEntrypoint { plugin_id },
|
||||
))
|
||||
}
|
||||
PluginTableMsgOut::ToggleShowGeneratedEntrypoints {
|
||||
|
||||
let msg_out = run(
|
||||
&application_manager,
|
||||
global_hotkey_manager,
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
Task::done(ManagementAppPluginMsgOut::Inner(
|
||||
ManagementAppPluginMsgIn::ToggleShowGeneratedEntrypoint {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
},
|
||||
))
|
||||
}
|
||||
PluginTableMsgOut::ShortcutCaptured(plugin_id, entrypoint_id, shortcut) => {
|
||||
let backend_client = backend_api.clone();
|
||||
shortcut,
|
||||
)
|
||||
.unwrap_or_else(|err| SettingsPluginMsgOut::Outer(SettingsMsg::HandleBackendError(err.into())));
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client
|
||||
.set_global_entrypoint_shortcut(plugin_id, entrypoint_id, shortcut)
|
||||
.await?;
|
||||
|
||||
let plugins = backend_client.plugins().await?;
|
||||
let global_entrypoint_shortcuts =
|
||||
backend_client.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_client.get_entrypoint_search_aliases().await?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
PluginTableMsgOut::AliasChanged(plugin_id, entrypoint_id, shortcut) => {
|
||||
let backend_client = backend_api.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client
|
||||
.set_entrypoint_search_alias(plugin_id, entrypoint_id, shortcut)
|
||||
.await?;
|
||||
|
||||
let plugins = backend_client.plugins().await?;
|
||||
let global_entrypoint_shortcuts =
|
||||
backend_client.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_client.get_entrypoint_search_aliases().await?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
Task::done(msg_out)
|
||||
}
|
||||
})
|
||||
PluginTableMsgOut::AliasChanged(plugin_id, entrypoint_id, shortcut) => {
|
||||
let application_manager = application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
application_manager.set_entrypoint_search_alias(plugin_id, entrypoint_id, shortcut)?;
|
||||
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts =
|
||||
application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(
|
||||
result,
|
||||
|(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ManagementAppPluginMsgIn::ToggleShowEntrypoint { plugin_id } => {
|
||||
SettingsPluginMsgIn::ToggleShowEntrypoint { plugin_id } => {
|
||||
let plugins = {
|
||||
let mut plugin_data = self.plugin_data.borrow_mut();
|
||||
let settings_plugin_data = plugin_data.plugins_state.get_mut(&plugin_id).unwrap();
|
||||
|
|
@ -309,7 +288,7 @@ impl ManagementAppPluginsState {
|
|||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppPluginMsgIn::ToggleShowGeneratedEntrypoint {
|
||||
SettingsPluginMsgIn::ToggleShowGeneratedEntrypoint {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
|
|
@ -334,7 +313,7 @@ impl ManagementAppPluginsState {
|
|||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppPluginMsgIn::PluginPreferenceMsg(msg) => {
|
||||
SettingsPluginMsgIn::PluginPreferenceMsg(msg) => {
|
||||
match msg {
|
||||
PluginPreferencesMsg::UpdatePreferenceValue {
|
||||
plugin_id,
|
||||
|
|
@ -347,39 +326,38 @@ impl ManagementAppPluginsState {
|
|||
user_data.clone(),
|
||||
);
|
||||
|
||||
let backend_api = backend_api.clone();
|
||||
let application_manager = application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_api
|
||||
.set_preference_value(plugin_id, entrypoint_id, id, user_data.to_user_data())
|
||||
.await?;
|
||||
application_manager.set_preference_value(
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
id,
|
||||
user_data.to_user_data(),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(result, |()| {
|
||||
ManagementAppPluginMsgOut::Outer(ManagementAppMsg::Noop)
|
||||
})
|
||||
},
|
||||
|result| handle_backend_error(result, |()| SettingsPluginMsgOut::Outer(SettingsMsg::Noop)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ManagementAppPluginMsgIn::FetchPlugins => {
|
||||
let backend_api = backend_api.clone();
|
||||
SettingsPluginMsgIn::FetchPlugins => {
|
||||
let application_manager = self.application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
let plugins = backend_api.plugins().await?;
|
||||
let global_entrypoint_shortcuts = backend_api.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_api.get_entrypoint_search_aliases().await?;
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts = application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(result, |(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
|
|
@ -388,29 +366,29 @@ impl ManagementAppPluginsState {
|
|||
},
|
||||
)
|
||||
}
|
||||
ManagementAppPluginMsgIn::PluginsReloaded(plugins, shortcuts, entrypoint_aliases) => {
|
||||
SettingsPluginMsgIn::PluginsReloaded(plugins, shortcuts, entrypoint_aliases) => {
|
||||
self.apply_plugin_fetch(plugins, shortcuts, entrypoint_aliases);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
ManagementAppPluginMsgIn::RemovePlugin { plugin_id } => {
|
||||
SettingsPluginMsgIn::RemovePlugin { plugin_id } => {
|
||||
self.selected_item = SelectedItem::None;
|
||||
|
||||
let backend_client = backend_api.clone();
|
||||
let application_manager = application_manager.clone();
|
||||
|
||||
Task::perform(
|
||||
async move {
|
||||
backend_client.remove_plugin(plugin_id).await?;
|
||||
application_manager.remove_plugin(plugin_id)?;
|
||||
|
||||
let plugins = backend_client.plugins().await?;
|
||||
let global_entrypoint_shortcuts = backend_client.get_global_entrypoint_shortcuts().await?;
|
||||
let entrypoint_aliases = backend_client.get_entrypoint_search_aliases().await?;
|
||||
let plugins = application_manager.plugins()?;
|
||||
let global_entrypoint_shortcuts = application_manager.get_global_entrypoint_shortcuts()?;
|
||||
let entrypoint_aliases = application_manager.get_entrypoint_search_aliases()?;
|
||||
|
||||
Ok((plugins, global_entrypoint_shortcuts, entrypoint_aliases))
|
||||
},
|
||||
|result| {
|
||||
handle_backend_error(result, |(plugins, global_entrypoint_shortcuts, entrypoint_aliases)| {
|
||||
ManagementAppPluginMsgOut::Inner(ManagementAppPluginMsgIn::PluginsReloaded(
|
||||
SettingsPluginMsgOut::Inner(SettingsPluginMsgIn::PluginsReloaded(
|
||||
plugins,
|
||||
global_entrypoint_shortcuts,
|
||||
entrypoint_aliases,
|
||||
|
|
@ -419,12 +397,10 @@ impl ManagementAppPluginsState {
|
|||
},
|
||||
)
|
||||
}
|
||||
ManagementAppPluginMsgIn::DownloadPlugin { plugin_id } => {
|
||||
Task::done(ManagementAppPluginMsgOut::Outer(ManagementAppMsg::DownloadPlugin {
|
||||
plugin_id,
|
||||
}))
|
||||
SettingsPluginMsgIn::DownloadPlugin { plugin_id } => {
|
||||
Task::done(SettingsPluginMsgOut::Outer(SettingsMsg::DownloadPlugin { plugin_id }))
|
||||
}
|
||||
ManagementAppPluginMsgIn::SelectItem(selected_item) => {
|
||||
SettingsPluginMsgIn::SelectItem(selected_item) => {
|
||||
self.selected_item = selected_item;
|
||||
|
||||
Task::none()
|
||||
|
|
@ -522,11 +498,11 @@ impl ManagementAppPluginsState {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn view(&self) -> Element<ManagementAppPluginMsgIn> {
|
||||
pub fn view(&self) -> Element<SettingsPluginMsgIn> {
|
||||
let table: Element<_> = self
|
||||
.table_state
|
||||
.view()
|
||||
.map(|msg| ManagementAppPluginMsgIn::PluginTableMsg(msg));
|
||||
.map(|msg| SettingsPluginMsgIn::PluginTableMsg(msg));
|
||||
|
||||
let table: Element<_> = container(table).padding(Padding::new(8.0)).into();
|
||||
|
||||
|
|
@ -593,7 +569,7 @@ impl ManagementAppPluginsState {
|
|||
|
||||
column_content.push(
|
||||
preferences_ui(plugin_id.clone(), None, &plugin.preferences, &self.preference_user_data)
|
||||
.map(|msg| ManagementAppPluginMsgIn::PluginPreferenceMsg(msg)),
|
||||
.map(|msg| SettingsPluginMsgIn::PluginPreferenceMsg(msg)),
|
||||
);
|
||||
|
||||
let content: Element<_> = column(column_content).spacing(12).into();
|
||||
|
|
@ -614,7 +590,7 @@ impl ManagementAppPluginsState {
|
|||
let check_for_updates_button: Element<_> = button(check_for_updates_text_container)
|
||||
.width(Length::Fill)
|
||||
.class(ButtonStyle::Primary)
|
||||
.on_press(ManagementAppPluginMsgIn::DownloadPlugin {
|
||||
.on_press(SettingsPluginMsgIn::DownloadPlugin {
|
||||
plugin_id: plugin.plugin_id.clone(),
|
||||
})
|
||||
.into();
|
||||
|
|
@ -632,7 +608,7 @@ impl ManagementAppPluginsState {
|
|||
let remove_button: Element<_> = button(remove_button_text_container)
|
||||
.width(Length::Fill)
|
||||
.class(ButtonStyle::Destructive)
|
||||
.on_press(ManagementAppPluginMsgIn::RemovePlugin {
|
||||
.on_press(SettingsPluginMsgIn::RemovePlugin {
|
||||
plugin_id: plugin.plugin_id.clone(),
|
||||
})
|
||||
.into();
|
||||
|
|
@ -699,7 +675,7 @@ impl ManagementAppPluginsState {
|
|||
&entrypoint.preferences,
|
||||
&self.preference_user_data,
|
||||
)
|
||||
.map(|msg| ManagementAppPluginMsgIn::PluginPreferenceMsg(msg)),
|
||||
.map(|msg| SettingsPluginMsgIn::PluginPreferenceMsg(msg)),
|
||||
);
|
||||
|
||||
let column: Element<_> = column(column_content).spacing(12).into();
|
||||
|
|
@ -717,9 +693,9 @@ impl ManagementAppPluginsState {
|
|||
SelectedItem::NewPlugin { repository_url } => {
|
||||
let url_input: Element<_> = text_input("Enter Git Repository URL", &repository_url)
|
||||
.on_input(|value| {
|
||||
ManagementAppPluginMsgIn::SelectItem(SelectedItem::NewPlugin { repository_url: value })
|
||||
SettingsPluginMsgIn::SelectItem(SelectedItem::NewPlugin { repository_url: value })
|
||||
})
|
||||
.on_submit(ManagementAppPluginMsgIn::DownloadPlugin {
|
||||
.on_submit(SettingsPluginMsgIn::DownloadPlugin {
|
||||
plugin_id: PluginId::from_string(repository_url),
|
||||
})
|
||||
.into();
|
||||
|
|
@ -805,12 +781,12 @@ impl ManagementAppPluginsState {
|
|||
|
||||
let top_button_action = match plugin_url {
|
||||
Some(plugin_url) => {
|
||||
ManagementAppPluginMsgIn::DownloadPlugin {
|
||||
SettingsPluginMsgIn::DownloadPlugin {
|
||||
plugin_id: PluginId::from_string(plugin_url),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
ManagementAppPluginMsgIn::SelectItem(SelectedItem::NewPlugin {
|
||||
SettingsPluginMsgIn::SelectItem(SelectedItem::NewPlugin {
|
||||
repository_url: Default::default(),
|
||||
})
|
||||
}
|
||||
|
|
@ -960,10 +936,10 @@ impl PluginPreferenceUserDataState {
|
|||
|
||||
pub fn handle_backend_error<T>(
|
||||
result: RequestResult<T>,
|
||||
convert: impl FnOnce(T) -> ManagementAppPluginMsgOut,
|
||||
) -> ManagementAppPluginMsgOut {
|
||||
convert: impl FnOnce(T) -> SettingsPluginMsgOut,
|
||||
) -> SettingsPluginMsgOut {
|
||||
match result {
|
||||
Ok(val) => convert(val),
|
||||
Err(err) => ManagementAppPluginMsgOut::Outer(ManagementAppMsg::HandleBackendError(err)),
|
||||
Err(err) => SettingsPluginMsgOut::Outer(SettingsMsg::HandleBackendError(err)),
|
||||
}
|
||||
}
|
||||
|
|
@ -19,11 +19,11 @@ use iced::widget::text_input;
|
|||
use iced_fonts::bootstrap::dash;
|
||||
use iced_fonts::bootstrap::plus;
|
||||
|
||||
use crate::theme::Element;
|
||||
use crate::theme::button::ButtonStyle;
|
||||
use crate::theme::container::ContainerStyle;
|
||||
use crate::theme::text::TextStyle;
|
||||
use crate::views::plugins::PluginPreferenceUserDataState;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::button::ButtonStyle;
|
||||
use crate::ui::settings::theme::container::ContainerStyle;
|
||||
use crate::ui::settings::theme::text::TextStyle;
|
||||
use crate::ui::settings::views::plugins::PluginPreferenceUserDataState;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PluginPreferencesMsg {
|
||||
|
|
@ -9,7 +9,6 @@ use gauntlet_common::model::SettingsEntrypointType;
|
|||
use gauntlet_common::model::SettingsPlugin;
|
||||
use iced::Alignment;
|
||||
use iced::Length;
|
||||
use iced::Task;
|
||||
use iced::advanced::text::Shaping;
|
||||
use iced::padding;
|
||||
use iced::widget::Space;
|
||||
|
|
@ -25,15 +24,15 @@ use iced::widget::text_input;
|
|||
use iced_fonts::bootstrap::caret_down;
|
||||
use iced_fonts::bootstrap::caret_right;
|
||||
|
||||
use crate::components::shortcut_selector::ShortcutData;
|
||||
use crate::components::shortcut_selector::shortcut_selector;
|
||||
use crate::theme::Element;
|
||||
use crate::theme::button::ButtonStyle;
|
||||
use crate::theme::container::ContainerStyle;
|
||||
use crate::theme::text_input::TextInputStyle;
|
||||
use crate::views::plugins::PluginDataContainer;
|
||||
use crate::views::plugins::SelectedItem;
|
||||
use crate::views::plugins::SettingsPluginData;
|
||||
use crate::ui::settings::components::shortcut_selector::ShortcutData;
|
||||
use crate::ui::settings::components::shortcut_selector::shortcut_selector;
|
||||
use crate::ui::settings::theme::Element;
|
||||
use crate::ui::settings::theme::button::ButtonStyle;
|
||||
use crate::ui::settings::theme::container::ContainerStyle;
|
||||
use crate::ui::settings::theme::text_input::TextInputStyle;
|
||||
use crate::ui::settings::views::plugins::PluginDataContainer;
|
||||
use crate::ui::settings::views::plugins::SelectedItem;
|
||||
use crate::ui::settings::views::plugins::SettingsPluginData;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PluginTableMsgIn {
|
||||
|
|
@ -85,47 +84,47 @@ impl PluginTableState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: PluginTableMsgIn) -> Task<PluginTableMsgOut> {
|
||||
pub fn update(&mut self, message: PluginTableMsgIn) -> PluginTableMsgOut {
|
||||
match message {
|
||||
PluginTableMsgIn::EnabledToggleItem(item) => {
|
||||
match item {
|
||||
EnabledItem::Plugin { enabled, plugin_id } => {
|
||||
Task::done(PluginTableMsgOut::SetPluginState { enabled, plugin_id })
|
||||
PluginTableMsgOut::SetPluginState { enabled, plugin_id }
|
||||
}
|
||||
EnabledItem::Entrypoint {
|
||||
enabled,
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
Task::done(PluginTableMsgOut::SetEntrypointState {
|
||||
PluginTableMsgOut::SetEntrypointState {
|
||||
enabled,
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PluginTableMsgIn::SelectItem(item) => Task::done(PluginTableMsgOut::SelectItem(item)),
|
||||
PluginTableMsgIn::SelectItem(item) => PluginTableMsgOut::SelectItem(item),
|
||||
PluginTableMsgIn::ToggleShowEntrypoints { plugin_id } => {
|
||||
Task::done(PluginTableMsgOut::ToggleShowEntrypoints { plugin_id })
|
||||
PluginTableMsgOut::ToggleShowEntrypoints { plugin_id }
|
||||
}
|
||||
PluginTableMsgIn::ToggleShowGeneratedEntrypoints {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
} => {
|
||||
Task::done(PluginTableMsgOut::ToggleShowGeneratedEntrypoints {
|
||||
PluginTableMsgOut::ToggleShowGeneratedEntrypoints {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
PluginTableMsgIn::ShortcutCaptured(plugin_id, entrypoint_id, shortcut) => {
|
||||
Task::done(PluginTableMsgOut::ShortcutCaptured(plugin_id, entrypoint_id, shortcut))
|
||||
PluginTableMsgOut::ShortcutCaptured(plugin_id, entrypoint_id, shortcut)
|
||||
}
|
||||
PluginTableMsgIn::AliasChanged(plugin_id, entrypoint_id, alias) => {
|
||||
let alias = alias.trim().to_owned();
|
||||
let alias = if alias.is_empty() { None } else { Some(alias) };
|
||||
|
||||
Task::done(PluginTableMsgOut::AliasChanged(plugin_id, entrypoint_id, alias))
|
||||
PluginTableMsgOut::AliasChanged(plugin_id, entrypoint_id, alias)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ pub mod hud;
|
|||
#[cfg(target_os = "linux")]
|
||||
pub mod x11_focus;
|
||||
|
||||
pub struct WindowState {
|
||||
pub struct MainWindowState {
|
||||
pub main_window_id: Option<window::Id>,
|
||||
focused: bool,
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
@ -31,14 +31,14 @@ pub struct WindowState {
|
|||
open_position: Position,
|
||||
}
|
||||
|
||||
impl WindowState {
|
||||
impl MainWindowState {
|
||||
pub fn new(
|
||||
window_position_file: Option<PathBuf>,
|
||||
close_on_unfocus: bool,
|
||||
window_position_mode: WindowPositionMode,
|
||||
#[cfg(target_os = "linux")] wayland: bool,
|
||||
#[cfg(target_os = "linux")] layer_shell: bool,
|
||||
) -> WindowState {
|
||||
) -> MainWindowState {
|
||||
let open_position = window_position_file
|
||||
.as_ref()
|
||||
.map(|window_position_file| fs::read_to_string(window_position_file).ok())
|
||||
|
|
@ -73,7 +73,7 @@ impl WindowState {
|
|||
}
|
||||
}
|
||||
|
||||
impl WindowState {
|
||||
impl MainWindowState {
|
||||
pub fn handle_action(&mut self, action: WindowActionMsg) -> Task<AppMsg> {
|
||||
match action {
|
||||
WindowActionMsg::SetWindowPositionMode { mode } => {
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
pub mod cli;
|
||||
pub mod detached_process;
|
||||
pub mod dirs;
|
||||
pub mod model;
|
||||
pub mod rpc;
|
||||
|
||||
pub const SETTINGS_ENV: &'static str = "__GAUNTLET_INTERNAL_SETTINGS__";
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum SettingsEnvData {
|
||||
OpenPluginPreferences { plugin_id: String },
|
||||
OpenEntrypointPreferences { plugin_id: String, entrypoint_id: String },
|
||||
}
|
||||
|
||||
pub fn settings_env_data_to_string(data: SettingsEnvData) -> String {
|
||||
serde_json::to_string(&data).expect("unable to serialize settings env data")
|
||||
}
|
||||
|
||||
pub fn settings_env_data_from_string(data: String) -> SettingsEnvData {
|
||||
serde_json::from_str(&data).expect("unable to serialize settings env data")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use gauntlet_utils::channel::RequestResult;
|
||||
|
|
@ -7,15 +6,9 @@ use tokio::sync::Mutex;
|
|||
use tonic::Request;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
use crate::model::DownloadStatus;
|
||||
use crate::model::EntrypointId;
|
||||
use crate::model::LocalSaveData;
|
||||
use crate::model::PhysicalShortcut;
|
||||
use crate::model::PluginId;
|
||||
use crate::model::PluginPreferenceUserData;
|
||||
use crate::model::SettingsPlugin;
|
||||
use crate::model::SettingsTheme;
|
||||
use crate::model::WindowPositionMode;
|
||||
use crate::rpc::grpc::RpcBincode;
|
||||
use crate::rpc::grpc::RpcSaveLocalPluginRequest;
|
||||
use crate::rpc::grpc::rpc_backend_client::RpcBackendClient;
|
||||
|
|
@ -42,69 +35,6 @@ pub trait BackendForToolsApi {
|
|||
async fn save_local_plugin(&self, path: String) -> RequestResult<LocalSaveData>;
|
||||
}
|
||||
|
||||
#[boundary_gen(bincode, grpc)]
|
||||
#[tonic::async_trait]
|
||||
pub trait BackendForSettingsApi {
|
||||
async fn wayland_global_shortcuts_enabled(&self) -> RequestResult<bool>;
|
||||
|
||||
async fn plugins(&self) -> RequestResult<HashMap<PluginId, SettingsPlugin>>;
|
||||
|
||||
async fn set_plugin_state(&self, plugin_id: PluginId, enabled: bool) -> RequestResult<()>;
|
||||
|
||||
async fn set_entrypoint_state(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
enabled: bool,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn set_global_shortcut(&self, shortcut: Option<PhysicalShortcut>) -> RequestResult<Option<String>>;
|
||||
|
||||
async fn get_global_shortcut(&self) -> RequestResult<(Option<PhysicalShortcut>, Option<String>)>;
|
||||
|
||||
async fn set_global_entrypoint_shortcut(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
shortcut: Option<PhysicalShortcut>,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn get_global_entrypoint_shortcuts(
|
||||
&self,
|
||||
) -> RequestResult<HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>>;
|
||||
|
||||
async fn set_entrypoint_search_alias(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
alias: Option<String>,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn get_entrypoint_search_aliases(&self) -> RequestResult<HashMap<(PluginId, EntrypointId), String>>;
|
||||
|
||||
async fn set_theme(&self, theme: SettingsTheme) -> RequestResult<()>;
|
||||
|
||||
async fn get_theme(&self) -> RequestResult<SettingsTheme>;
|
||||
|
||||
async fn set_window_position_mode(&self, mode: WindowPositionMode) -> RequestResult<()>;
|
||||
|
||||
async fn get_window_position_mode(&self) -> RequestResult<WindowPositionMode>;
|
||||
|
||||
async fn set_preference_value(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
preference_id: String,
|
||||
preference_value: PluginPreferenceUserData,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn download_plugin(&self, plugin_id: PluginId) -> RequestResult<()>;
|
||||
|
||||
async fn download_status(&self) -> RequestResult<HashMap<PluginId, DownloadStatus>>;
|
||||
|
||||
async fn remove_plugin(&self, plugin_id: PluginId) -> RequestResult<()>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GrpcBackendApi {
|
||||
client: Arc<Mutex<RpcBackendClient<Channel>>>,
|
||||
|
|
@ -117,20 +47,6 @@ impl GrpcBackendApi {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn backend_for_settings_api(&self, bytes: Vec<u8>) -> RequestResult<Vec<u8>> {
|
||||
let request = RpcBincode { data: bytes };
|
||||
|
||||
let mut client = self.client.lock().await;
|
||||
|
||||
let response = client
|
||||
.backend_for_settings_api(Request::new(request))
|
||||
.await?
|
||||
.into_inner()
|
||||
.data;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub async fn backend_for_cli_api(&self, bytes: Vec<u8>) -> RequestResult<Vec<u8>> {
|
||||
let request = RpcBincode { data: bytes };
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,8 @@ use tonic::Status;
|
|||
use tonic::transport::Server;
|
||||
|
||||
use crate::rpc::backend_api::BackendForCliApi;
|
||||
use crate::rpc::backend_api::BackendForSettingsApi;
|
||||
use crate::rpc::backend_api::BackendForToolsApi;
|
||||
use crate::rpc::backend_api::handle_grpc_request_backend_for_cli_api;
|
||||
use crate::rpc::backend_api::handle_grpc_request_backend_for_settings_api;
|
||||
use crate::rpc::grpc::RpcBincode;
|
||||
use crate::rpc::grpc::RpcSaveLocalPluginRequest;
|
||||
use crate::rpc::grpc::RpcSaveLocalPluginResponse;
|
||||
|
|
@ -33,12 +31,11 @@ pub async fn wait_for_backend_server() {
|
|||
pub async fn start_backend_server(
|
||||
cli: Box<dyn BackendForCliApi + Sync + Send>,
|
||||
tools: Box<dyn BackendForToolsApi + Sync + Send>,
|
||||
settings: Box<dyn BackendForSettingsApi + Sync + Send>,
|
||||
) {
|
||||
let addr = "127.0.0.1:42320".parse().unwrap();
|
||||
|
||||
Server::builder()
|
||||
.add_service(RpcBackendServer::new(RpcBackendServerImpl::new(cli, tools, settings)))
|
||||
.add_service(RpcBackendServer::new(RpcBackendServerImpl::new(cli, tools)))
|
||||
.serve(addr)
|
||||
.await
|
||||
.expect("unable to start backend server");
|
||||
|
|
@ -47,16 +44,11 @@ pub async fn start_backend_server(
|
|||
struct RpcBackendServerImpl {
|
||||
cli: Box<dyn BackendForCliApi + Sync + Send>,
|
||||
tools: Box<dyn BackendForToolsApi + Sync + Send>,
|
||||
settings: Box<dyn BackendForSettingsApi + Sync + Send>,
|
||||
}
|
||||
|
||||
impl RpcBackendServerImpl {
|
||||
pub fn new(
|
||||
cli: Box<dyn BackendForCliApi + Sync + Send>,
|
||||
tools: Box<dyn BackendForToolsApi + Sync + Send>,
|
||||
settings: Box<dyn BackendForSettingsApi + Sync + Send>,
|
||||
) -> Self {
|
||||
Self { cli, settings, tools }
|
||||
pub fn new(cli: Box<dyn BackendForCliApi + Sync + Send>, tools: Box<dyn BackendForToolsApi + Sync + Send>) -> Self {
|
||||
Self { cli, tools }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,14 +62,6 @@ impl RpcBackend for RpcBackendServerImpl {
|
|||
Ok(Response::new(RpcBincode { data: encoded }))
|
||||
}
|
||||
|
||||
async fn backend_for_settings_api(&self, request: Request<RpcBincode>) -> Result<Response<RpcBincode>, Status> {
|
||||
let data = request.into_inner().data;
|
||||
|
||||
let encoded = handle_grpc_request_backend_for_settings_api(self.settings.as_ref(), data).await?;
|
||||
|
||||
Ok(Response::new(RpcBincode { data: encoded }))
|
||||
}
|
||||
|
||||
async fn save_local_plugin(
|
||||
&self,
|
||||
request: Request<RpcSaveLocalPluginRequest>,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ pub trait FrontendApi {
|
|||
|
||||
async fn hide_window(&self) -> RequestResult<()>;
|
||||
|
||||
async fn show_settings(&self) -> RequestResult<()>;
|
||||
|
||||
async fn show_preference_required_view(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,9 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use gauntlet_utils::channel::RequestResult;
|
||||
use gauntlet_utils_macros::boundary_gen;
|
||||
|
||||
use crate::model::DownloadStatus;
|
||||
use crate::model::EntrypointId;
|
||||
use crate::model::LocalSaveData;
|
||||
use crate::model::PhysicalShortcut;
|
||||
use crate::model::PluginId;
|
||||
use crate::model::PluginPreferenceUserData;
|
||||
use crate::model::SettingsPlugin;
|
||||
use crate::model::SettingsTheme;
|
||||
use crate::model::WindowPositionMode;
|
||||
|
||||
#[allow(async_fn_in_trait)]
|
||||
#[boundary_gen(in_process)]
|
||||
|
|
@ -28,63 +20,4 @@ pub trait ServerGrpcApi {
|
|||
) -> RequestResult<()>;
|
||||
|
||||
async fn save_local_plugin(&self, path: String) -> RequestResult<LocalSaveData>;
|
||||
|
||||
async fn plugins(&self) -> RequestResult<HashMap<PluginId, SettingsPlugin>>;
|
||||
|
||||
async fn set_plugin_state(&self, plugin_id: PluginId, enabled: bool) -> RequestResult<()>;
|
||||
|
||||
async fn set_entrypoint_state(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
enabled: bool,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn set_global_shortcut(&self, shortcut: Option<PhysicalShortcut>) -> RequestResult<Option<String>>;
|
||||
|
||||
async fn get_global_shortcut(&self) -> RequestResult<Option<(PhysicalShortcut, Option<String>)>>;
|
||||
|
||||
async fn set_global_entrypoint_shortcut(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
shortcut: Option<PhysicalShortcut>,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn get_global_entrypoint_shortcuts(
|
||||
&self,
|
||||
) -> RequestResult<HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>>;
|
||||
|
||||
async fn set_entrypoint_search_alias(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
alias: Option<String>,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn get_entrypoint_search_aliases(&self) -> RequestResult<HashMap<(PluginId, EntrypointId), String>>;
|
||||
|
||||
async fn set_theme(&self, theme: SettingsTheme) -> RequestResult<()>;
|
||||
|
||||
async fn get_theme(&self) -> RequestResult<SettingsTheme>;
|
||||
|
||||
async fn set_window_position_mode(&self, mode: WindowPositionMode) -> RequestResult<()>;
|
||||
|
||||
async fn get_window_position_mode(&self) -> RequestResult<WindowPositionMode>;
|
||||
|
||||
async fn set_preference_value(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
preference_id: String,
|
||||
preference_value: PluginPreferenceUserData,
|
||||
) -> RequestResult<()>;
|
||||
|
||||
async fn download_plugin(&self, plugin_id: PluginId) -> RequestResult<()>;
|
||||
|
||||
async fn download_status(&self) -> RequestResult<HashMap<PluginId, DownloadStatus>>;
|
||||
|
||||
async fn remove_plugin(&self, plugin_id: PluginId) -> RequestResult<()>;
|
||||
|
||||
async fn wayland_global_shortcuts_enabled(&self) -> RequestResult<bool>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ pub trait BackendForPluginRuntimeApi {
|
|||
async fn ui_update_loading_bar(&self, entrypoint_id: EntrypointId, show: bool) -> RequestResult<()>;
|
||||
async fn ui_show_hud(&self, display: String) -> RequestResult<()>;
|
||||
async fn ui_hide_window(&self) -> RequestResult<()>;
|
||||
async fn ui_show_settings(&self) -> RequestResult<()>;
|
||||
async fn ui_get_action_id_for_shortcut(
|
||||
&self,
|
||||
entrypoint_id: EntrypointId,
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
[package]
|
||||
name = "gauntlet-management-client"
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# workspaces
|
||||
gauntlet-common.workspace = true
|
||||
gauntlet-common-ui.workspace = true
|
||||
gauntlet-utils.workspace = true
|
||||
|
||||
# shared
|
||||
anyhow.workspace = true
|
||||
iced.workspace = true
|
||||
iced_fonts.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
itertools.workspace = true
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
mod components;
|
||||
mod theme;
|
||||
mod ui;
|
||||
mod views;
|
||||
|
||||
pub fn start_management_client() {
|
||||
ui::run();
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
gauntlet_management_client::start_management_client();
|
||||
}
|
||||
|
|
@ -1,17 +1,22 @@
|
|||
use anyhow::anyhow;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use deno_core::OpState;
|
||||
use deno_core::op2;
|
||||
use gauntlet_common::detached_process::CommandExt;
|
||||
use gauntlet_common_plugin_runtime::api::BackendForPluginRuntimeApi;
|
||||
use gauntlet_common_plugin_runtime::api::BackendForPluginRuntimeApiProxy;
|
||||
|
||||
use crate::deno::GauntletJsError;
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn open_settings() -> Result<(), GauntletJsError> {
|
||||
let current_exe = std::env::current_exe().map_err(|err| anyhow!(err))?;
|
||||
#[op2(async)]
|
||||
pub async fn open_settings(state: Rc<RefCell<OpState>>) -> Result<(), GauntletJsError> {
|
||||
let api = {
|
||||
let state = state.borrow();
|
||||
|
||||
std::process::Command::new(current_exe)
|
||||
.args(["settings"])
|
||||
.spawn_detached()
|
||||
.map_err(|err| anyhow!(err))?;
|
||||
let api = state.borrow::<BackendForPluginRuntimeApiProxy>().clone();
|
||||
|
||||
Ok(())
|
||||
api
|
||||
};
|
||||
|
||||
api.ui_show_settings().await.map_err(Into::into)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -412,7 +412,6 @@ impl DataDbRepository {
|
|||
}
|
||||
|
||||
pub fn list_plugins_and_entrypoints(&self) -> anyhow::Result<Vec<(DbReadPlugin, Vec<DbReadPluginEntrypoint>)>> {
|
||||
// language=SQLite
|
||||
let plugins = self.list_plugins()?;
|
||||
|
||||
let result = plugins
|
||||
|
|
|
|||
|
|
@ -961,6 +961,12 @@ impl BackendForPluginRuntimeApi for BackendForPluginRuntimeApiImpl {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn ui_show_settings(&self) -> RequestResult<()> {
|
||||
self.frontend_api.show_settings().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn ui_get_action_id_for_shortcut(
|
||||
&self,
|
||||
entrypoint_id: EntrypointId,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl PluginLoader {
|
|||
self.download_status_holder.download_status()
|
||||
}
|
||||
|
||||
pub fn download_plugin(&self, plugin_id: PluginId) -> anyhow::Result<()> {
|
||||
pub fn download_plugin(&self, plugin_id: PluginId) {
|
||||
let download_status_guard = self.download_status_holder.download_started(plugin_id.clone());
|
||||
|
||||
let data_db_repository = self.db_repository.clone();
|
||||
|
|
@ -104,8 +104,6 @@ impl PluginLoader {
|
|||
})
|
||||
})
|
||||
.expect("failed to spawn thread");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn save_local_plugin(&self, path: &str) -> anyhow::Result<PluginId> {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use gauntlet_common::SETTINGS_ENV;
|
||||
use gauntlet_common::SettingsEnvData;
|
||||
use gauntlet_common::detached_process::CommandExt;
|
||||
use gauntlet_common::dirs::Dirs;
|
||||
use gauntlet_common::model::DownloadStatus;
|
||||
use gauntlet_common::model::EntrypointId;
|
||||
|
|
@ -30,7 +27,6 @@ use gauntlet_common::rpc::frontend_api::FrontendApi;
|
|||
use gauntlet_common::rpc::frontend_api::FrontendApiProxy;
|
||||
use gauntlet_common::rpc::frontend_api::FrontendApiRequestData;
|
||||
use gauntlet_common::rpc::frontend_api::FrontendApiResponseData;
|
||||
use gauntlet_common::settings_env_data_to_string;
|
||||
use gauntlet_common_plugin_runtime::model::JsPluginCode;
|
||||
use gauntlet_common_plugin_runtime::model::JsPluginPermissionsExec;
|
||||
use gauntlet_common_plugin_runtime::model::JsPluginPermissionsFileSystem;
|
||||
|
|
@ -174,7 +170,7 @@ impl ApplicationManager {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn download_plugin(&self, plugin_id: PluginId) -> anyhow::Result<()> {
|
||||
pub fn download_plugin(&self, plugin_id: PluginId) {
|
||||
self.plugin_downloader.download_plugin(plugin_id)
|
||||
}
|
||||
|
||||
|
|
@ -571,7 +567,7 @@ impl ApplicationManager {
|
|||
.set_global_entrypoint_shortcut(global_hotkey_manager, plugin_id, entrypoint_id, shortcut)
|
||||
}
|
||||
|
||||
pub fn get_global_entrypoint_shortcut(
|
||||
pub fn get_global_entrypoint_shortcuts(
|
||||
&self,
|
||||
) -> anyhow::Result<HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>> {
|
||||
self.settings.global_entrypoint_shortcuts()
|
||||
|
|
@ -812,36 +808,6 @@ impl ApplicationManager {
|
|||
.expect("failed to toggle window");
|
||||
}
|
||||
|
||||
pub fn open_settings_window(&self) {
|
||||
let current_exe = std::env::current_exe().expect("unable to get current_exe");
|
||||
|
||||
std::process::Command::new(current_exe)
|
||||
.args(["settings"])
|
||||
.spawn_detached()
|
||||
.expect("failed to execute settings process");
|
||||
}
|
||||
|
||||
pub fn open_settings_window_preferences(&self, plugin_id: PluginId, entrypoint_id: Option<EntrypointId>) {
|
||||
let data = if let Some(entrypoint_id) = entrypoint_id {
|
||||
SettingsEnvData::OpenEntrypointPreferences {
|
||||
plugin_id: plugin_id.to_string(),
|
||||
entrypoint_id: entrypoint_id.to_string(),
|
||||
}
|
||||
} else {
|
||||
SettingsEnvData::OpenPluginPreferences {
|
||||
plugin_id: plugin_id.to_string(),
|
||||
}
|
||||
};
|
||||
|
||||
let current_exe = std::env::current_exe().expect("unable to get current_exe");
|
||||
|
||||
std::process::Command::new(current_exe)
|
||||
.args(["settings"])
|
||||
.env(SETTINGS_ENV, settings_env_data_to_string(data))
|
||||
.spawn_detached()
|
||||
.expect("failed to execute settings process"); // this can fail in dev if binary was replaced by more recent compilation
|
||||
}
|
||||
|
||||
fn reload_plugin(&self, plugin_id: PluginId) -> anyhow::Result<()> {
|
||||
tracing::info!(target = "plugin", "Reloading plugin with id: {:?}", plugin_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use gauntlet_common::model::DownloadStatus;
|
||||
use gauntlet_common::model::EntrypointId;
|
||||
use gauntlet_common::model::LocalSaveData;
|
||||
use gauntlet_common::model::PhysicalShortcut;
|
||||
use gauntlet_common::model::PluginId;
|
||||
use gauntlet_common::model::PluginPreferenceUserData;
|
||||
use gauntlet_common::model::SettingsPlugin;
|
||||
use gauntlet_common::model::SettingsTheme;
|
||||
use gauntlet_common::model::WindowPositionMode;
|
||||
use gauntlet_common::rpc::backend_api::BackendForCliApi;
|
||||
use gauntlet_common::rpc::backend_api::BackendForSettingsApi;
|
||||
use gauntlet_common::rpc::backend_api::BackendForToolsApi;
|
||||
use gauntlet_common::rpc::backend_server::start_backend_server;
|
||||
use gauntlet_common::rpc::server_grpc_api::ServerGrpcApi;
|
||||
|
|
@ -33,7 +24,6 @@ pub async fn run_grpc_server(grpc_api: ServerGrpcApiProxy) {
|
|||
start_backend_server(
|
||||
Box::new(BackendServerImpl::new(grpc_api.clone())),
|
||||
Box::new(BackendServerImpl::new(grpc_api.clone())),
|
||||
Box::new(BackendServerImpl::new(grpc_api.clone())),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
@ -77,197 +67,3 @@ impl BackendForToolsApi for BackendServerImpl {
|
|||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl BackendForSettingsApi for BackendServerImpl {
|
||||
async fn wayland_global_shortcuts_enabled(&self) -> RequestResult<bool> {
|
||||
self.proxy.wayland_global_shortcuts_enabled().await
|
||||
}
|
||||
|
||||
async fn plugins(&self) -> RequestResult<HashMap<PluginId, SettingsPlugin>> {
|
||||
self.proxy.plugins().await
|
||||
}
|
||||
|
||||
async fn set_plugin_state(&self, plugin_id: PluginId, enabled: bool) -> RequestResult<()> {
|
||||
let result = self.proxy.set_plugin_state(plugin_id, enabled).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_plugin_state' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_entrypoint_state(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
enabled: bool,
|
||||
) -> RequestResult<()> {
|
||||
let result = self.proxy.set_entrypoint_state(plugin_id, entrypoint_id, enabled).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_entrypoint_state' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_global_shortcut(&self, shortcut: Option<PhysicalShortcut>) -> RequestResult<Option<String>> {
|
||||
let result = self.proxy.set_global_shortcut(shortcut).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_global_shortcut' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
async fn get_global_shortcut(&self) -> RequestResult<(Option<PhysicalShortcut>, Option<String>)> {
|
||||
let result = self
|
||||
.proxy
|
||||
.get_global_shortcut()
|
||||
.await?
|
||||
.map(|(shortcut, error)| (Some(shortcut), error))
|
||||
.unwrap_or((None, None));
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn set_global_entrypoint_shortcut(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
shortcut: Option<PhysicalShortcut>,
|
||||
) -> RequestResult<()> {
|
||||
let result = self
|
||||
.proxy
|
||||
.set_global_entrypoint_shortcut(plugin_id, entrypoint_id, shortcut)
|
||||
.await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_global_entrypoint_shortcut' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
async fn get_global_entrypoint_shortcuts(
|
||||
&self,
|
||||
) -> RequestResult<HashMap<(PluginId, EntrypointId), (PhysicalShortcut, Option<String>)>> {
|
||||
self.proxy.get_global_entrypoint_shortcuts().await
|
||||
}
|
||||
|
||||
async fn set_entrypoint_search_alias(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
alias: Option<String>,
|
||||
) -> RequestResult<()> {
|
||||
let result = self
|
||||
.proxy
|
||||
.set_entrypoint_search_alias(plugin_id, entrypoint_id, alias)
|
||||
.await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_entrypoint_search_alias' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
async fn get_entrypoint_search_aliases(&self) -> RequestResult<HashMap<(PluginId, EntrypointId), String>> {
|
||||
self.proxy.get_entrypoint_search_aliases().await
|
||||
}
|
||||
|
||||
async fn set_theme(&self, theme: SettingsTheme) -> RequestResult<()> {
|
||||
self.proxy.set_theme(theme).await
|
||||
}
|
||||
|
||||
async fn get_theme(&self) -> RequestResult<SettingsTheme> {
|
||||
self.proxy.get_theme().await
|
||||
}
|
||||
|
||||
async fn set_window_position_mode(&self, mode: WindowPositionMode) -> RequestResult<()> {
|
||||
self.proxy.set_window_position_mode(mode).await
|
||||
}
|
||||
|
||||
async fn get_window_position_mode(&self) -> RequestResult<WindowPositionMode> {
|
||||
self.proxy.get_window_position_mode().await
|
||||
}
|
||||
|
||||
async fn set_preference_value(
|
||||
&self,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
preference_id: String,
|
||||
preference_value: PluginPreferenceUserData,
|
||||
) -> RequestResult<()> {
|
||||
let result = self
|
||||
.proxy
|
||||
.set_preference_value(plugin_id, entrypoint_id, preference_id, preference_value)
|
||||
.await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'set_preference_value' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn download_plugin(&self, plugin_id: PluginId) -> RequestResult<()> {
|
||||
let result = self.proxy.download_plugin(plugin_id).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'download_plugin' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn download_status(&self) -> RequestResult<HashMap<PluginId, DownloadStatus>> {
|
||||
self.proxy.download_status().await
|
||||
}
|
||||
|
||||
async fn remove_plugin(&self, plugin_id: PluginId) -> RequestResult<()> {
|
||||
let result = self.proxy.remove_plugin(plugin_id).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
tracing::warn!(
|
||||
target = "rpc",
|
||||
"error occurred when handling 'remove_plugin' request {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ service RpcBackend {
|
|||
// cli
|
||||
rpc BackendForCliApi(RpcBincode) returns (RpcBincode);
|
||||
|
||||
// settings
|
||||
rpc BackendForSettingsApi(RpcBincode) returns (RpcBincode);
|
||||
|
||||
// dev tools, screenshot gen
|
||||
rpc SaveLocalPlugin (RpcSaveLocalPluginRequest) returns (RpcSaveLocalPluginResponse);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue