mirror of
https://github.com/project-gauntlet/gauntlet.git
synced 2025-12-23 10:35:53 +00:00
Require preferences to be specified if plugin provides no default value
This commit is contained in:
parent
0f3e33ec1a
commit
d1cfbeb036
16 changed files with 539 additions and 112 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1012,6 +1012,8 @@ dependencies = [
|
|||
"anyhow",
|
||||
"gix",
|
||||
"prost 0.12.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-typescript": "^11.1.5",
|
||||
"@types/react": "^18.2.35",
|
||||
"@project-gauntlet/api": "*",
|
||||
"@project-gauntlet/typings": "*",
|
||||
"@project-gauntlet/deno": "*",
|
||||
"rollup": "^4.3.0",
|
||||
|
|
|
|||
|
|
@ -103,6 +103,25 @@ async function handleKeyboardEvent(event: NotReactsKeyboardEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
async function checkRequiredPreferences(entrypointId: string): Promise<boolean> {
|
||||
const pluginPreferencesRequired = InternalApi.plugin_preferences_required();
|
||||
const entrypointPreferencesRequired = InternalApi.entrypoint_preferences_required(entrypointId);
|
||||
|
||||
return pluginPreferencesRequired || entrypointPreferencesRequired;
|
||||
}
|
||||
|
||||
async function checkRequiredPreferencesAndAsk(entrypointId: string): Promise<boolean> {
|
||||
const pluginPreferencesRequired = await InternalApi.plugin_preferences_required();
|
||||
const entrypointPreferencesRequired = await InternalApi.entrypoint_preferences_required(entrypointId);
|
||||
|
||||
const required = pluginPreferencesRequired || entrypointPreferencesRequired;
|
||||
if (required) {
|
||||
InternalApi.show_preferences_required_view(entrypointId, pluginPreferencesRequired, entrypointPreferencesRequired)
|
||||
}
|
||||
|
||||
return required;
|
||||
}
|
||||
|
||||
async function runLoop() {
|
||||
while (true) {
|
||||
InternalApi.op_log_trace("plugin_loop", "Waiting for next plugin event...")
|
||||
|
|
@ -127,6 +146,10 @@ async function runLoop() {
|
|||
}
|
||||
case "OpenView": {
|
||||
try {
|
||||
if (await checkRequiredPreferencesAndAsk(pluginEvent.entrypointId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const View: FC = (await import(`gauntlet:entrypoint?${pluginEvent.entrypointId}`)).default;
|
||||
const { render } = await import("gauntlet:renderer");
|
||||
latestRootUiWidget = render(pluginEvent.frontend, pluginEvent.entrypointId, "View", <View/>);
|
||||
|
|
@ -137,6 +160,10 @@ async function runLoop() {
|
|||
}
|
||||
case "RunCommand": {
|
||||
try {
|
||||
if (await checkRequiredPreferencesAndAsk(pluginEvent.entrypointId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const command: () => void = (await import(`gauntlet:entrypoint?${pluginEvent.entrypointId}`)).default;
|
||||
command()
|
||||
} catch (e) {
|
||||
|
|
@ -146,6 +173,10 @@ async function runLoop() {
|
|||
}
|
||||
case "RunGeneratedCommand": {
|
||||
try {
|
||||
if (await checkRequiredPreferencesAndAsk(pluginEvent.entrypointId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
runGeneratedCommand(pluginEvent.entrypointId)
|
||||
} catch (e) {
|
||||
console.error("Error occurred when running a generated command", pluginEvent.entrypointId, e)
|
||||
|
|
@ -153,14 +184,18 @@ async function runLoop() {
|
|||
break;
|
||||
}
|
||||
case "OpenInlineView": {
|
||||
const endpoint_id = InternalApi.op_inline_view_endpoint_id();
|
||||
const endpointId = InternalApi.op_inline_view_endpoint_id();
|
||||
|
||||
if (endpointId) {
|
||||
if (await checkRequiredPreferences(endpointId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (endpoint_id) {
|
||||
try {
|
||||
const Handler: FC<{ text: string }> = (await import(`gauntlet:entrypoint?${endpoint_id}`)).default;
|
||||
const Handler: FC<{ text: string }> = (await import(`gauntlet:entrypoint?${endpointId}`)).default;
|
||||
const { render } = await import("gauntlet:renderer");
|
||||
|
||||
latestRootUiWidget = render("default", endpoint_id, "InlineView", <Handler text={pluginEvent.text}/>);
|
||||
latestRootUiWidget = render("default", endpointId, "InlineView", <Handler text={pluginEvent.text}/>);
|
||||
|
||||
if (latestRootUiWidget.widgetChildren.length === 0) {
|
||||
InternalApi.op_log_debug("plugin_loop", `Inline view rendered no children, clearing inline view...`)
|
||||
|
|
|
|||
3
js/typings/index.d.ts
vendored
3
js/typings/index.d.ts
vendored
|
|
@ -97,6 +97,9 @@ interface InternalApi {
|
|||
get_command_generator_entrypoint_ids(): Promise<string[]>
|
||||
get_plugin_preferences(): Record<string, any>;
|
||||
get_entrypoint_preferences(entrypointId: string): Record<string, any>;
|
||||
plugin_preferences_required(): Promise<boolean>;
|
||||
entrypoint_preferences_required(entrypointId: string): Promise<boolean>;
|
||||
show_preferences_required_view(entrypointId: string, pluginPreferencesRequired: boolean, entrypointPreferencesRequired: boolean): void;
|
||||
|
||||
load_search_index(searchItems: AdditionalSearchItem[]): Promise<void>;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ pub enum NativeUiRequestData {
|
|||
top_level_view: bool,
|
||||
container: NativeUiWidget,
|
||||
},
|
||||
ShowPreferenceRequiredView {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
plugin_preferences_required: bool,
|
||||
entrypoint_preferences_required: bool
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use tonic::{Request, Response, Status};
|
||||
|
||||
use common::model::{EntrypointId, PluginId, RenderLocation};
|
||||
use common::rpc::{RpcClearInlineViewRequest, RpcClearInlineViewResponse, RpcRenderLocation, RpcReplaceViewRequest, RpcReplaceViewResponse, RpcShowWindowRequest, RpcShowWindowResponse};
|
||||
use common::rpc::{RpcClearInlineViewRequest, RpcClearInlineViewResponse, RpcRenderLocation, RpcReplaceViewRequest, RpcReplaceViewResponse, RpcShowPreferenceRequiredViewRequest, RpcShowPreferenceRequiredViewResponse, RpcShowWindowRequest, RpcShowWindowResponse};
|
||||
use common::rpc::rpc_frontend_server::RpcFrontend;
|
||||
use utils::channel::RequestSender;
|
||||
|
||||
|
|
@ -71,6 +71,27 @@ impl RpcFrontend for RpcFrontendServerImpl {
|
|||
|
||||
Ok(Response::new(RpcShowWindowResponse::default()))
|
||||
}
|
||||
|
||||
async fn show_preference_required_view(&self, request: Request<RpcShowPreferenceRequiredViewRequest>) -> Result<Response<RpcShowPreferenceRequiredViewResponse>, Status> {
|
||||
let request = request.into_inner();
|
||||
let plugin_id = request.plugin_id;
|
||||
let entrypoint_id = request.entrypoint_id;
|
||||
let plugin_preferences_required = request.plugin_preferences_required;
|
||||
let entrypoint_preferences_required = request.entrypoint_preferences_required;
|
||||
|
||||
let data = NativeUiRequestData::ShowPreferenceRequiredView {
|
||||
plugin_id: PluginId::from_string(plugin_id),
|
||||
entrypoint_id: EntrypointId::from_string(entrypoint_id),
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required,
|
||||
};
|
||||
|
||||
match self.context_tx.send_receive(data).await {
|
||||
NativeUiResponseData::Nothing => {}
|
||||
};
|
||||
|
||||
Ok(Response::new(RpcShowPreferenceRequiredViewResponse::default()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use iced::futures::SinkExt;
|
|||
use iced::keyboard::Key;
|
||||
use iced::keyboard::key::Named;
|
||||
use iced::Application;
|
||||
use iced::widget::{column, container, horizontal_rule, scrollable, text_input};
|
||||
use iced::widget::{button, column, container, horizontal_rule, scrollable, text, text_input};
|
||||
use iced::widget::text_input::focus;
|
||||
use iced::window::{change_level, Level, Position, reposition};
|
||||
use iced_aw::graphics::icons;
|
||||
|
|
@ -18,7 +18,7 @@ use tonic::transport::Server;
|
|||
|
||||
use client_context::ClientContext;
|
||||
use common::model::{EntrypointId, PluginId, PropertyValue, RenderLocation};
|
||||
use common::rpc::{BackendClient, RpcEntrypointTypeSearchResult, RpcEventKeyboardEvent, RpcEventRenderView, RpcEventRunCommand, RpcEventRunGeneratedCommand, RpcEventViewEvent, RpcRequestRunCommandRequest, RpcRequestRunGeneratedCommandRequest, RpcRequestViewRenderRequest, RpcSearchRequest, RpcSendKeyboardEventRequest, RpcSendViewEventRequest, RpcUiPropertyValue, RpcUiWidgetId};
|
||||
use common::rpc::{BackendClient, RpcEntrypointTypeSearchResult, RpcEventKeyboardEvent, RpcEventRenderView, RpcEventRunCommand, RpcEventRunGeneratedCommand, RpcEventViewEvent, RpcOpenSettingsWindowPreferencesRequest, RpcRequestRunCommandRequest, RpcRequestRunGeneratedCommandRequest, RpcRequestViewRenderRequest, RpcSearchRequest, RpcSendKeyboardEventRequest, RpcSendViewEventRequest, RpcUiPropertyValue, RpcUiWidgetId};
|
||||
use common::rpc::rpc_backend_client::RpcBackendClient;
|
||||
use common::rpc::rpc_frontend_server::RpcFrontendServer;
|
||||
use common::rpc::rpc_ui_property_value::Value;
|
||||
|
|
@ -46,18 +46,26 @@ pub struct AppModel {
|
|||
search_results: Vec<NativeUiSearchResult>,
|
||||
request_rx: Arc<TokioRwLock<RequestReceiver<NativeUiRequestData, NativeUiResponseData>>>,
|
||||
search_field_id: text_input::Id,
|
||||
view_data: Option<ViewData>,
|
||||
plugin_view_data: Option<PluginViewData>,
|
||||
prompt: Option<String>,
|
||||
waiting_for_next_unfocus: bool,
|
||||
global_hotkey_manager: GlobalHotKeyManager,
|
||||
preference_required_view: Option<PreferenceRequiredViewData>,
|
||||
}
|
||||
|
||||
struct ViewData {
|
||||
struct PluginViewData {
|
||||
top_level_view: bool,
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
}
|
||||
|
||||
struct PreferenceRequiredViewData {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
plugin_preferences_required: bool,
|
||||
entrypoint_preferences_required: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AppMsg {
|
||||
OpenView {
|
||||
|
|
@ -85,6 +93,16 @@ pub enum AppMsg {
|
|||
FontLoaded(Result<(), font::Error>),
|
||||
ShowWindow,
|
||||
HideWindow,
|
||||
ShowPreferenceRequiredView {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: EntrypointId,
|
||||
plugin_preferences_required: bool,
|
||||
entrypoint_preferences_required: bool
|
||||
},
|
||||
OpenSettingsPreferences {
|
||||
plugin_id: PluginId,
|
||||
entrypoint_id: Option<EntrypointId>,
|
||||
},
|
||||
}
|
||||
|
||||
const WINDOW_WIDTH: f32 = 650.0;
|
||||
|
|
@ -147,9 +165,10 @@ impl Application for AppModel {
|
|||
search_results: vec![],
|
||||
search_field_id: text_input::Id::unique(),
|
||||
prompt: None,
|
||||
view_data: None,
|
||||
plugin_view_data: None,
|
||||
waiting_for_next_unfocus: false,
|
||||
global_hotkey_manager,
|
||||
preference_required_view: None,
|
||||
},
|
||||
Command::batch([
|
||||
change_level(window::Id::MAIN, Level::AlwaysOnTop),
|
||||
|
|
@ -166,7 +185,7 @@ impl Application for AppModel {
|
|||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||
match message {
|
||||
AppMsg::OpenView { plugin_id, entrypoint_id } => {
|
||||
self.view_data.replace(ViewData {
|
||||
self.plugin_view_data.replace(PluginViewData {
|
||||
top_level_view: true,
|
||||
plugin_id: plugin_id.clone(),
|
||||
entrypoint_id: entrypoint_id.clone(),
|
||||
|
|
@ -235,7 +254,7 @@ impl Application for AppModel {
|
|||
Command::none()
|
||||
}
|
||||
AppMsg::SetTopLevelView(top_level_view) => {
|
||||
match &mut self.view_data {
|
||||
match &mut self.plugin_view_data {
|
||||
None => Command::none(),
|
||||
Some(view_data) => {
|
||||
view_data.top_level_view = top_level_view;
|
||||
|
|
@ -253,7 +272,7 @@ impl Application for AppModel {
|
|||
Key::Named(Named::ArrowDown) => iced::widget::focus_next(),
|
||||
Key::Named(Named::Escape) => self.previous_view(),
|
||||
Key::Character(char) => {
|
||||
if let Some(_) = self.view_data {
|
||||
if let Some(_) = self.plugin_view_data {
|
||||
let (plugin_id, entrypoint_id) = {
|
||||
let client_context = self.client_context.read().expect("lock is poisoned");
|
||||
(client_context.get_view_plugin_id(), client_context.get_view_entrypoint_id())
|
||||
|
|
@ -362,11 +381,89 @@ impl Application for AppModel {
|
|||
}
|
||||
AppMsg::ShowWindow => self.show_window(),
|
||||
AppMsg::HideWindow => self.hide_window(),
|
||||
AppMsg::ShowPreferenceRequiredView {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required
|
||||
} => {
|
||||
self.preference_required_view = Some(PreferenceRequiredViewData {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required,
|
||||
});
|
||||
Command::none()
|
||||
}
|
||||
AppMsg::OpenSettingsPreferences { plugin_id, entrypoint_id, } => {
|
||||
let mut backend_client = self.backend_client.clone();
|
||||
|
||||
Command::perform(async move {
|
||||
let request = RpcOpenSettingsWindowPreferencesRequest {
|
||||
plugin_id: plugin_id.to_string(),
|
||||
entrypoint_id: entrypoint_id.map(|val| val.to_string()).unwrap_or_default(),
|
||||
};
|
||||
|
||||
backend_client.open_settings_window_preferences(Request::new(request))
|
||||
.await
|
||||
.unwrap();
|
||||
}, |_| AppMsg::Noop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<'_, Self::Message> {
|
||||
match &self.view_data {
|
||||
if let Some(view_data) = &self.preference_required_view {
|
||||
let PreferenceRequiredViewData { plugin_id, entrypoint_id, plugin_preferences_required, entrypoint_preferences_required } = view_data;
|
||||
|
||||
let (description_text, msg) = match (plugin_preferences_required, entrypoint_preferences_required) {
|
||||
(true, true) => {
|
||||
// TODO do not show "entrypoint" name to user
|
||||
let description_text = "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 { 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 { plugin_id: plugin_id.clone(), entrypoint_id: Some(entrypoint_id.clone()) };
|
||||
(description_text, msg)
|
||||
}
|
||||
(true, false) => {
|
||||
let description_text = "Before using, plugin preferences need to be specified";
|
||||
let msg = AppMsg::OpenSettingsPreferences { plugin_id: plugin_id.clone(), entrypoint_id: None };
|
||||
(description_text, msg)
|
||||
}
|
||||
(false, false) => unreachable!()
|
||||
};
|
||||
|
||||
let description: Element<_> = text(description_text)
|
||||
.into();
|
||||
|
||||
let button_label: Element<_> = text("Open Settings")
|
||||
.into();
|
||||
|
||||
let button: Element<_> = button(button_label)
|
||||
.on_press(msg)
|
||||
.into();
|
||||
|
||||
let content: Element<_> = column([
|
||||
description,
|
||||
button
|
||||
]).into();
|
||||
|
||||
let content: Element<_> = container(content)
|
||||
.style(ContainerStyle::Background)
|
||||
.height(Length::Fixed(WINDOW_HEIGHT))
|
||||
.width(Length::Fixed(WINDOW_WIDTH))
|
||||
.into();
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
match &self.plugin_view_data {
|
||||
None => {
|
||||
let input: Element<_> = text_input("Search...", self.prompt.as_ref().unwrap_or(&"".to_owned()))
|
||||
.on_input(AppMsg::PromptChanged)
|
||||
|
|
@ -440,7 +537,7 @@ impl Application for AppModel {
|
|||
// element.explain(iced::color!(0xFF0000))
|
||||
element
|
||||
}
|
||||
Some(ViewData { plugin_id, entrypoint_id: _, top_level_view: _ }) => {
|
||||
Some(PluginViewData { plugin_id, entrypoint_id: _, top_level_view: _ }) => {
|
||||
let container_element: Element<_> = view_container(self.client_context.clone(), plugin_id.to_owned())
|
||||
.into();
|
||||
|
||||
|
|
@ -504,13 +601,16 @@ impl Application for AppModel {
|
|||
impl AppModel {
|
||||
fn hide_window(&mut self) -> Command<AppMsg> {
|
||||
self.prompt = None;
|
||||
self.view_data = None;
|
||||
self.plugin_view_data = None;
|
||||
self.search_results = vec![];
|
||||
self.close_preference_required_view();
|
||||
|
||||
window::change_mode(window::Id::MAIN, window::Mode::Hidden)
|
||||
}
|
||||
|
||||
fn show_window(&mut self) -> Command<AppMsg> {
|
||||
self.close_preference_required_view();
|
||||
|
||||
Command::batch([
|
||||
window::change_mode(window::Id::MAIN, window::Mode::Windowed),
|
||||
window::gain_focus(window::Id::MAIN),
|
||||
|
|
@ -520,20 +620,24 @@ impl AppModel {
|
|||
])
|
||||
}
|
||||
|
||||
fn close_preference_required_view(&mut self) {
|
||||
self.preference_required_view = None;
|
||||
}
|
||||
|
||||
fn previous_view(&mut self) -> Command<AppMsg> {
|
||||
match &self.view_data {
|
||||
match &self.plugin_view_data {
|
||||
None => {
|
||||
self.hide_window()
|
||||
}
|
||||
Some(ViewData { top_level_view: true, .. }) => {
|
||||
self.view_data.take();
|
||||
Some(PluginViewData { top_level_view: true, .. }) => {
|
||||
self.plugin_view_data.take();
|
||||
|
||||
Command::batch([
|
||||
reposition(window::Id::MAIN, Position::Centered, Size::new(WINDOW_WIDTH, WINDOW_HEIGHT)),
|
||||
window::resize(window::Id::MAIN, Size::new(WINDOW_WIDTH, WINDOW_HEIGHT))
|
||||
])
|
||||
}
|
||||
Some(ViewData { top_level_view: false, plugin_id, entrypoint_id }) => {
|
||||
Some(PluginViewData { top_level_view: false, plugin_id, entrypoint_id }) => {
|
||||
self.open_view(plugin_id.clone(), entrypoint_id.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -656,6 +760,21 @@ async fn request_loop(
|
|||
NativeUiRequestData::ShowWindow => {
|
||||
app_msg = AppMsg::ShowWindow;
|
||||
|
||||
responder.respond(NativeUiResponseData::Nothing)
|
||||
}
|
||||
NativeUiRequestData::ShowPreferenceRequiredView {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required
|
||||
} => {
|
||||
app_msg = AppMsg::ShowPreferenceRequiredView {
|
||||
plugin_id,
|
||||
entrypoint_id,
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required
|
||||
};
|
||||
|
||||
responder.respond(NativeUiResponseData::Nothing)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ gix = { version = "0.52.0", features = ["blocking-http-transport-curl"] }
|
|||
anyhow = { version = "1", features = ["backtrace"] }
|
||||
tonic = "0.11.0"
|
||||
prost = "0.12.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.11.0"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::fmt::Debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use tonic::transport::Channel;
|
||||
|
||||
|
|
@ -218,3 +219,23 @@ pub fn plugin_preference_user_data_from_npb(value: RpcNoProtoBufPluginPreference
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ use iced_table::table;
|
|||
use tonic::Request;
|
||||
|
||||
use common::model::{EntrypointId, PluginId};
|
||||
use common::rpc::{BackendClient, plugin_preference_user_data_from_npb, plugin_preference_user_data_to_npb, RpcDownloadPluginRequest, RpcDownloadStatus, RpcDownloadStatusRequest, RpcEntrypointTypeSettings, RpcNoProtoBufPluginPreferenceUserData, RpcPluginPreference, RpcPluginPreferenceValueType, RpcPluginsRequest, RpcSetEntrypointStateRequest, RpcSetPluginStateRequest, RpcSetPreferenceValueRequest};
|
||||
use common::rpc::{BackendClient, plugin_preference_user_data_from_npb, plugin_preference_user_data_to_npb, RpcDownloadPluginRequest, RpcDownloadStatus, RpcDownloadStatusRequest, RpcEntrypointTypeSettings, RpcNoProtoBufPluginPreferenceUserData, RpcPluginPreference, RpcPluginPreferenceValueType, RpcPluginsRequest, RpcSetEntrypointStateRequest, RpcSetPluginStateRequest, RpcSetPreferenceValueRequest, settings_env_data_from_string, SettingsEnvData};
|
||||
use common::rpc::rpc_backend_client::RpcBackendClient;
|
||||
use common::rpc::rpc_ui_property_value::Value;
|
||||
|
||||
const SETTINGS_ENV: &'static str = "GAUNTLET_INTERNAL_SETTINGS";
|
||||
|
||||
pub fn run() {
|
||||
ManagementAppModel::run(Settings {
|
||||
id: None,
|
||||
|
|
@ -46,6 +48,10 @@ enum ManagementAppMsg {
|
|||
TableSyncHeader(scrollable::AbsoluteOffset),
|
||||
FontLoaded(Result<(), font::Error>),
|
||||
PluginsReloaded(HashMap<PluginId, Plugin>),
|
||||
InitialPluginsReloaded {
|
||||
plugins: HashMap<PluginId, Plugin>,
|
||||
select_item: SelectedItem,
|
||||
},
|
||||
ToggleShowEntrypoints {
|
||||
plugin_id: PluginId,
|
||||
},
|
||||
|
|
@ -207,6 +213,21 @@ impl Application for ManagementAppModel {
|
|||
anyhow::Ok(RpcBackendClient::connect("http://127.0.0.1:42320").await?)
|
||||
}).unwrap();
|
||||
|
||||
let settings_env_data = std::env::var(SETTINGS_ENV)
|
||||
.map(|val| settings_env_data_from_string(val))
|
||||
.ok();
|
||||
|
||||
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),
|
||||
},
|
||||
};
|
||||
|
||||
(
|
||||
ManagementAppModel {
|
||||
backend_client: backend_client.clone(),
|
||||
|
|
@ -230,8 +251,11 @@ impl Application for ManagementAppModel {
|
|||
async {
|
||||
reload_plugins(backend_client).await
|
||||
},
|
||||
ManagementAppMsg::PluginsReloaded,
|
||||
)
|
||||
|plugins| ManagementAppMsg::InitialPluginsReloaded {
|
||||
plugins,
|
||||
select_item
|
||||
},
|
||||
),
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
|
@ -256,75 +280,16 @@ impl Application for ManagementAppModel {
|
|||
Command::none()
|
||||
}
|
||||
ManagementAppMsg::PluginsReloaded(plugins) => {
|
||||
self.preference_user_data = plugins.iter()
|
||||
.map(|(plugin_id, plugin)| {
|
||||
let mut result = vec![];
|
||||
|
||||
for (name, user_data) in &plugin.preferences_user_data {
|
||||
result.push(((plugin_id.clone(), None, name.clone()), user_data.clone()))
|
||||
}
|
||||
|
||||
for (entrypoint_id, entrypoint) in &plugin.entrypoints {
|
||||
for (name, user_data) in &entrypoint.preferences_user_data {
|
||||
result.push(((plugin_id.clone(), Some(entrypoint_id.clone()), name.clone()), user_data.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let plugins = Rc::new(RefCell::new(plugins));
|
||||
self.plugins = plugins.clone();
|
||||
|
||||
let plugin_refs = plugins.borrow();
|
||||
|
||||
let mut plugin_refs: Vec<_> = plugin_refs
|
||||
.iter()
|
||||
.map(|(_, plugin)| plugin)
|
||||
.collect();
|
||||
|
||||
plugin_refs.sort_by_key(|plugin| &plugin.plugin_name);
|
||||
|
||||
self.rows = plugin_refs
|
||||
.iter()
|
||||
.flat_map(|plugin| {
|
||||
let mut result = vec![];
|
||||
|
||||
result.push(Row::Plugin {
|
||||
plugins: plugins.clone(),
|
||||
plugin_id: plugin.plugin_id.clone()
|
||||
});
|
||||
|
||||
if plugin.show_entrypoints {
|
||||
let mut entrypoints: Vec<_> = plugin.entrypoints
|
||||
.iter()
|
||||
.map(|(_, entrypoint)| entrypoint)
|
||||
.collect();
|
||||
|
||||
entrypoints.sort_by_key(|entrypoint| &entrypoint.entrypoint_name);
|
||||
|
||||
let mut entrypoints: Vec<_> = entrypoints
|
||||
.iter()
|
||||
.map(|entrypoint| {
|
||||
Row::Entrypoint {
|
||||
plugins: plugins.clone(),
|
||||
plugin_id: plugin.plugin_id.clone(),
|
||||
entrypoint_id: entrypoint.entrypoint_id.clone(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
result.append(&mut entrypoints);
|
||||
}
|
||||
|
||||
result
|
||||
})
|
||||
.collect();
|
||||
self.apply_plugin_reload(plugins);
|
||||
|
||||
Command::none()
|
||||
}
|
||||
ManagementAppMsg::InitialPluginsReloaded { plugins, select_item } => {
|
||||
self.apply_plugin_reload(plugins);
|
||||
self.selected_item = select_item;
|
||||
|
||||
Command::none()
|
||||
},
|
||||
ManagementAppMsg::SelectItem(selected_item) => {
|
||||
self.selected_item = selected_item;
|
||||
Command::none()
|
||||
|
|
@ -1481,6 +1446,76 @@ fn preferences_ui<'a>(
|
|||
column_content
|
||||
}
|
||||
|
||||
impl ManagementAppModel {
|
||||
fn apply_plugin_reload(&mut self, plugins: HashMap<PluginId, Plugin>) {
|
||||
self.preference_user_data = plugins.iter()
|
||||
.map(|(plugin_id, plugin)| {
|
||||
let mut result = vec![];
|
||||
|
||||
for (name, user_data) in &plugin.preferences_user_data {
|
||||
result.push(((plugin_id.clone(), None, name.clone()), user_data.clone()))
|
||||
}
|
||||
|
||||
for (entrypoint_id, entrypoint) in &plugin.entrypoints {
|
||||
for (name, user_data) in &entrypoint.preferences_user_data {
|
||||
result.push(((plugin_id.clone(), Some(entrypoint_id.clone()), name.clone()), user_data.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let plugins = Rc::new(RefCell::new(plugins));
|
||||
self.plugins = plugins.clone();
|
||||
|
||||
let plugin_refs = plugins.borrow();
|
||||
|
||||
let mut plugin_refs: Vec<_> = plugin_refs
|
||||
.iter()
|
||||
.map(|(_, plugin)| plugin)
|
||||
.collect();
|
||||
|
||||
plugin_refs.sort_by_key(|plugin| &plugin.plugin_name);
|
||||
|
||||
self.rows = plugin_refs
|
||||
.iter()
|
||||
.flat_map(|plugin| {
|
||||
let mut result = vec![];
|
||||
|
||||
result.push(Row::Plugin {
|
||||
plugins: plugins.clone(),
|
||||
plugin_id: plugin.plugin_id.clone()
|
||||
});
|
||||
|
||||
if plugin.show_entrypoints {
|
||||
let mut entrypoints: Vec<_> = plugin.entrypoints
|
||||
.iter()
|
||||
.map(|(_, entrypoint)| entrypoint)
|
||||
.collect();
|
||||
|
||||
entrypoints.sort_by_key(|entrypoint| &entrypoint.entrypoint_name);
|
||||
|
||||
let mut entrypoints: Vec<_> = entrypoints
|
||||
.iter()
|
||||
.map(|entrypoint| {
|
||||
Row::Entrypoint {
|
||||
plugins: plugins.clone(),
|
||||
plugin_id: plugin.plugin_id.clone(),
|
||||
entrypoint_id: entrypoint.entrypoint_id.clone(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
result.append(&mut entrypoints);
|
||||
}
|
||||
|
||||
result
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
async fn reload_plugins(mut backend_client: BackendClient) -> HashMap<PluginId, Plugin> {
|
||||
backend_client.plugins(Request::new(RpcPluginsRequest::default()))
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub(in crate) mod model;
|
|||
mod dirs;
|
||||
|
||||
const FRONTEND_ENV: &'static str = "GAUNTLET_INTERNAL_FRONTEND";
|
||||
const SETTINGS_ENV: &'static str = "GAUNTLET_INTERNAL_SETTINGS";
|
||||
|
||||
pub fn start_server() {
|
||||
if std::env::var(FRONTEND_ENV).is_ok() {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ pub enum JsUiRequestData {
|
|||
top_level_view: bool,
|
||||
container: IntermediateUiWidget,
|
||||
},
|
||||
ClearInlineView
|
||||
ClearInlineView,
|
||||
ShowPreferenceRequiredView {
|
||||
entrypoint_id: EntrypointId,
|
||||
plugin_preferences_required: bool,
|
||||
entrypoint_preferences_required: bool
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||
|
|
@ -200,9 +205,9 @@ fn from_intermediate_to_rpc_properties(value: HashMap<String, PropertyValue>) ->
|
|||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PreferenceUserData {
|
||||
Number(Option<f64>),
|
||||
String(Option<String>),
|
||||
Bool(Option<bool>),
|
||||
Number(f64),
|
||||
String(String),
|
||||
Bool(bool),
|
||||
ListOfStrings(Vec<String>),
|
||||
ListOfNumbers(Vec<f64>),
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ use tonic::Request;
|
|||
use tonic::transport::Channel;
|
||||
|
||||
use common::model::{EntrypointId, PluginId, PropertyValue, RenderLocation};
|
||||
use common::rpc::{FrontendClient, RpcClearInlineViewRequest, RpcRenderLocation, RpcReplaceViewRequest, RpcUiPropertyValue, RpcUiWidgetId};
|
||||
use common::rpc::{FrontendClient, RpcClearInlineViewRequest, RpcRenderLocation, RpcReplaceViewRequest, RpcShowPreferenceRequiredViewRequest, RpcUiPropertyValue, RpcUiWidgetId};
|
||||
use common::rpc::rpc_frontend_client::RpcFrontendClient;
|
||||
use common::rpc::rpc_frontend_server::RpcFrontend;
|
||||
use component_model::{Children, Component, create_component_model, PropertyType};
|
||||
|
|
@ -427,6 +427,9 @@ deno_core::extension!(
|
|||
load_search_index,
|
||||
get_command_generator_entrypoint_ids,
|
||||
fetch_action_id_for_shortcut,
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required,
|
||||
show_preferences_required_view,
|
||||
],
|
||||
options = {
|
||||
event_receiver: EventReceiver,
|
||||
|
|
@ -536,6 +539,70 @@ fn asset_data_blocking(state: Rc<RefCell<OpState>>, path: String) -> anyhow::Res
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn plugin_preferences_required(state: Rc<RefCell<OpState>>) -> anyhow::Result<bool> {
|
||||
let (plugin_id, repository) = {
|
||||
let state = state.borrow();
|
||||
|
||||
let plugin_id = state
|
||||
.borrow::<PluginData>()
|
||||
.plugin_id()
|
||||
.clone();
|
||||
|
||||
let repository = state
|
||||
.borrow::<DataDbRepository>()
|
||||
.clone();
|
||||
|
||||
(plugin_id, repository)
|
||||
};
|
||||
|
||||
let DbReadPlugin { preferences, preferences_user_data, .. } = repository
|
||||
.get_plugin_by_id(&plugin_id.to_string()).await?;
|
||||
|
||||
Ok(all_preferences_required(preferences, preferences_user_data))
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn entrypoint_preferences_required(state: Rc<RefCell<OpState>>, entrypoint_id: String) -> anyhow::Result<bool> {
|
||||
let (plugin_id, repository) = {
|
||||
let state = state.borrow();
|
||||
|
||||
let plugin_id = state
|
||||
.borrow::<PluginData>()
|
||||
.plugin_id()
|
||||
.clone();
|
||||
|
||||
let repository = state
|
||||
.borrow::<DataDbRepository>()
|
||||
.clone();
|
||||
|
||||
(plugin_id, repository)
|
||||
};
|
||||
|
||||
let DbReadPluginEntrypoint { preferences, preferences_user_data, .. } = repository
|
||||
.get_entrypoint_by_id(&plugin_id.to_string(), &entrypoint_id).await?;
|
||||
|
||||
Ok(all_preferences_required(preferences, preferences_user_data))
|
||||
}
|
||||
|
||||
|
||||
#[op]
|
||||
fn show_preferences_required_view(state: Rc<RefCell<OpState>>, entrypoint_id: String, plugin_preferences_required: bool, entrypoint_preferences_required: bool) -> anyhow::Result<()> {
|
||||
let data = JsUiRequestData::ShowPreferenceRequiredView {
|
||||
entrypoint_id: EntrypointId::from_string(entrypoint_id),
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required
|
||||
};
|
||||
|
||||
match make_request(&state, data).context("ShowPreferenceRequiredView frontend response")? {
|
||||
JsUiResponseData::Nothing => {
|
||||
tracing::trace!(target = "renderer_rs", "Calling show_preferences_required_view returned");
|
||||
Ok(())
|
||||
}
|
||||
value @ _ => panic!("unsupported response type {:?}", value),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[op]
|
||||
async fn op_plugin_get_pending_event(state: Rc<RefCell<OpState>>) -> anyhow::Result<JsUiEvent> {
|
||||
|
|
@ -777,25 +844,23 @@ fn preferences_to_js(
|
|||
preferences.into_iter()
|
||||
.map(|(name, preference)| {
|
||||
let user_data = match preferences_user_data.remove(&name) {
|
||||
None => {
|
||||
match preference {
|
||||
DbPluginPreference::Number { default, .. } => PreferenceUserData::Number(default),
|
||||
DbPluginPreference::String { default, .. } => PreferenceUserData::String(default),
|
||||
DbPluginPreference::Enum { default, .. } => PreferenceUserData::String(default),
|
||||
DbPluginPreference::Bool { default, .. } => PreferenceUserData::Bool(default),
|
||||
DbPluginPreference::ListOfStrings { default, .. } => PreferenceUserData::ListOfStrings(default.unwrap_or(vec![])),
|
||||
DbPluginPreference::ListOfNumbers { default, .. } => PreferenceUserData::ListOfNumbers(default.unwrap_or(vec![])),
|
||||
DbPluginPreference::ListOfEnums { default, .. } => PreferenceUserData::ListOfStrings(default.unwrap_or(vec![])),
|
||||
}
|
||||
None => match preference {
|
||||
DbPluginPreference::Number { default, .. } => PreferenceUserData::Number(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::String { default, .. } => PreferenceUserData::String(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::Enum { default, .. } => PreferenceUserData::String(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::Bool { default, .. } => PreferenceUserData::Bool(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::ListOfStrings { default, .. } => PreferenceUserData::ListOfStrings(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::ListOfNumbers { default, .. } => PreferenceUserData::ListOfNumbers(default.expect("at this point preference should always have value")),
|
||||
DbPluginPreference::ListOfEnums { default, .. } => PreferenceUserData::ListOfStrings(default.expect("at this point preference should always have value")),
|
||||
}
|
||||
Some(user_data) => match user_data {
|
||||
DbPluginPreferenceUserData::Number { value } => PreferenceUserData::Number(value),
|
||||
DbPluginPreferenceUserData::String { value } => PreferenceUserData::String(value),
|
||||
DbPluginPreferenceUserData::Enum { value } => PreferenceUserData::String(value),
|
||||
DbPluginPreferenceUserData::Bool { value } => PreferenceUserData::Bool(value),
|
||||
DbPluginPreferenceUserData::ListOfStrings { value } => PreferenceUserData::ListOfStrings(value.unwrap_or(vec![])),
|
||||
DbPluginPreferenceUserData::ListOfNumbers { value } => PreferenceUserData::ListOfNumbers(value.unwrap_or(vec![])),
|
||||
DbPluginPreferenceUserData::ListOfEnums { value } => PreferenceUserData::ListOfStrings(value.unwrap_or(vec![])),
|
||||
DbPluginPreferenceUserData::Number { value } => PreferenceUserData::Number(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::String { value } => PreferenceUserData::String(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::Enum { value } => PreferenceUserData::String(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::Bool { value } => PreferenceUserData::Bool(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::ListOfStrings { value } => PreferenceUserData::ListOfStrings(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::ListOfNumbers { value } => PreferenceUserData::ListOfNumbers(value.expect("at this point preference should always have value")),
|
||||
DbPluginPreferenceUserData::ListOfEnums { value } => PreferenceUserData::ListOfStrings(value.expect("at this point preference should always have value")),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1020,6 +1085,21 @@ async fn make_request_async(plugin_id: PluginId, frontend_client: &mut FrontendC
|
|||
|
||||
nothing
|
||||
}
|
||||
JsUiRequestData::ShowPreferenceRequiredView { plugin_preferences_required, entrypoint_preferences_required, entrypoint_id } => {
|
||||
let request = Request::new(RpcShowPreferenceRequiredViewRequest {
|
||||
plugin_id: plugin_id.to_string(),
|
||||
entrypoint_id: entrypoint_id.to_string(),
|
||||
plugin_preferences_required,
|
||||
entrypoint_preferences_required,
|
||||
});
|
||||
|
||||
let nothing = frontend_client.show_preference_required_view(request)
|
||||
.await
|
||||
.map(|_| JsUiResponseData::Nothing)
|
||||
.map_err(|err| err.into());
|
||||
|
||||
nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1111,6 +1191,45 @@ fn from_js_to_intermediate_properties(
|
|||
Ok(vec.into_iter().collect())
|
||||
}
|
||||
|
||||
fn all_preferences_required(preferences: HashMap<String, DbPluginPreference>, preferences_user_data: HashMap<String, DbPluginPreferenceUserData>) -> bool {
|
||||
for (name, preference) in preferences {
|
||||
match preferences_user_data.get(&name) {
|
||||
None => {
|
||||
let no_default = match preference {
|
||||
DbPluginPreference::Number { default, .. } => default.is_none(),
|
||||
DbPluginPreference::String { default, .. } => default.is_none(),
|
||||
DbPluginPreference::Enum { default, .. } => default.is_none(),
|
||||
DbPluginPreference::Bool { default, .. } => default.is_none(),
|
||||
DbPluginPreference::ListOfStrings { default, .. } => default.is_none(),
|
||||
DbPluginPreference::ListOfNumbers { default, .. } => default.is_none(),
|
||||
DbPluginPreference::ListOfEnums { default, .. } => default.is_none(),
|
||||
};
|
||||
|
||||
if no_default {
|
||||
return true
|
||||
}
|
||||
}
|
||||
Some(preference) => {
|
||||
let no_value = match preference {
|
||||
DbPluginPreferenceUserData::Number { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::String { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::Enum { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::Bool { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::ListOfStrings { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::ListOfNumbers { value } => value.is_none(),
|
||||
DbPluginPreferenceUserData::ListOfEnums { value } => value.is_none(),
|
||||
};
|
||||
|
||||
if no_value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub struct PluginData {
|
||||
plugin_id: PluginId,
|
||||
inline_view_entrypoint_id: Option<String>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::collections::HashMap;
|
|||
use tonic::{Request, Response, Status};
|
||||
|
||||
use common::model::{DownloadStatus, EntrypointId, PluginId};
|
||||
use common::rpc::{RpcDownloadPluginRequest, RpcDownloadPluginResponse, RpcDownloadStatus, RpcDownloadStatusRequest, RpcDownloadStatusResponse, RpcDownloadStatusValue, RpcEntrypointTypeSearchResult, RpcEventRenderView, RpcEventRunCommand, RpcEventViewEvent, RpcPlugin, RpcPluginsRequest, RpcPluginsResponse, RpcRequestRunCommandRequest, RpcRequestRunCommandResponse, RpcRequestRunGeneratedCommandRequest, RpcRequestRunGeneratedCommandResponse, RpcRequestViewRenderRequest, RpcRequestViewRenderResponse, RpcSaveLocalPluginRequest, RpcSaveLocalPluginResponse, RpcSearchRequest, RpcSearchResponse, RpcSearchResult, RpcSendKeyboardEventRequest, RpcSendKeyboardEventResponse, RpcSendViewEventRequest, RpcSendViewEventResponse, RpcSetEntrypointStateRequest, RpcSetEntrypointStateResponse, RpcSetPluginStateRequest, RpcSetPluginStateResponse, RpcSetPreferenceValueRequest, RpcSetPreferenceValueResponse};
|
||||
use common::rpc::{RpcDownloadPluginRequest, RpcDownloadPluginResponse, RpcDownloadStatus, RpcDownloadStatusRequest, RpcDownloadStatusResponse, RpcDownloadStatusValue, RpcEntrypointTypeSearchResult, RpcEventRenderView, RpcEventRunCommand, RpcEventViewEvent, RpcOpenSettingsWindowPreferencesRequest, RpcOpenSettingsWindowPreferencesResponse, RpcOpenSettingsWindowRequest, RpcOpenSettingsWindowResponse, RpcPlugin, RpcPluginsRequest, RpcPluginsResponse, RpcRequestRunCommandRequest, RpcRequestRunCommandResponse, RpcRequestRunGeneratedCommandRequest, RpcRequestRunGeneratedCommandResponse, RpcRequestViewRenderRequest, RpcRequestViewRenderResponse, RpcSaveLocalPluginRequest, RpcSaveLocalPluginResponse, RpcSearchRequest, RpcSearchResponse, RpcSearchResult, RpcSendKeyboardEventRequest, RpcSendKeyboardEventResponse, RpcSendViewEventRequest, RpcSendViewEventResponse, RpcSetEntrypointStateRequest, RpcSetEntrypointStateResponse, RpcSetPluginStateRequest, RpcSetPluginStateResponse, RpcSetPreferenceValueRequest, RpcSetPreferenceValueResponse, settings_env_data_to_string, SettingsEnvData};
|
||||
use common::rpc::rpc_backend_server::{RpcBackend, RpcBackendServer};
|
||||
|
||||
use crate::{FRONTEND_ENV, SETTINGS_ENV};
|
||||
use crate::model::from_rpc_to_intermediate_value;
|
||||
use crate::plugins::ApplicationManager;
|
||||
use crate::search::{SearchIndex, SearchIndexPluginEntrypointType};
|
||||
|
|
@ -230,6 +231,35 @@ impl RpcBackend for RpcBackendServerImpl {
|
|||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
async fn open_settings_window(&self, _: Request<RpcOpenSettingsWindowRequest>) -> Result<Response<RpcOpenSettingsWindowResponse>, Status> {
|
||||
std::process::Command::new(std::env::current_exe()?)
|
||||
.args(["management"])
|
||||
.spawn()
|
||||
.expect("failed to execute settings process");
|
||||
|
||||
Ok(Response::new(RpcOpenSettingsWindowResponse::default()))
|
||||
}
|
||||
|
||||
async fn open_settings_window_preferences(&self, request: Request<RpcOpenSettingsWindowPreferencesRequest>) -> Result<Response<RpcOpenSettingsWindowPreferencesResponse>, Status> {
|
||||
let request = request.into_inner();
|
||||
let plugin_id = request.plugin_id;
|
||||
let entrypoint_id = request.entrypoint_id;
|
||||
|
||||
let data = if entrypoint_id.is_empty() {
|
||||
SettingsEnvData::OpenPluginPreferences { plugin_id }
|
||||
} else {
|
||||
SettingsEnvData::OpenEntrypointPreferences { plugin_id, entrypoint_id }
|
||||
};
|
||||
|
||||
std::process::Command::new(std::env::current_exe()?)
|
||||
.args(["management"])
|
||||
.env(SETTINGS_ENV, settings_env_data_to_string(data))
|
||||
.spawn()
|
||||
.expect("failed to execute settings process");
|
||||
|
||||
Ok(Response::new(RpcOpenSettingsWindowPreferencesResponse::default()))
|
||||
}
|
||||
|
||||
async fn save_local_plugin(&self, request: Request<RpcSaveLocalPluginRequest>) -> Result<Response<RpcSaveLocalPluginResponse>, Status> {
|
||||
let request = request.into_inner();
|
||||
let path = request.path;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ service RpcBackend {
|
|||
|
||||
rpc DownloadStatus (RpcDownloadStatusRequest) returns (RpcDownloadStatusResponse);
|
||||
|
||||
rpc OpenSettingsWindow (RpcOpenSettingsWindowRequest) returns (RpcOpenSettingsWindowResponse);
|
||||
rpc OpenSettingsWindowPreferences (RpcOpenSettingsWindowPreferencesRequest) returns (RpcOpenSettingsWindowPreferencesResponse);
|
||||
|
||||
// dev tools
|
||||
rpc SaveLocalPlugin (RpcSaveLocalPluginRequest) returns (RpcSaveLocalPluginResponse);
|
||||
}
|
||||
|
|
@ -123,6 +126,19 @@ message RpcDownloadStatusResponse {
|
|||
map<string, RpcDownloadStatusValue> status_per_plugin = 1;
|
||||
}
|
||||
|
||||
|
||||
message RpcOpenSettingsWindowRequest {
|
||||
}
|
||||
message RpcOpenSettingsWindowResponse {
|
||||
}
|
||||
|
||||
message RpcOpenSettingsWindowPreferencesRequest {
|
||||
string plugin_id = 1;
|
||||
string entrypoint_id = 2;
|
||||
}
|
||||
message RpcOpenSettingsWindowPreferencesResponse {
|
||||
}
|
||||
|
||||
message RpcSearchResult {
|
||||
string plugin_id = 1;
|
||||
string plugin_name = 2;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ service RpcFrontend {
|
|||
rpc ReplaceView (RpcReplaceViewRequest) returns (RpcReplaceViewResponse);
|
||||
rpc ClearInlineView (RpcClearInlineViewRequest) returns (RpcClearInlineViewResponse);
|
||||
rpc ShowWindow (RpcShowWindowRequest) returns (RpcShowWindowResponse);
|
||||
rpc ShowPreferenceRequiredView (RpcShowPreferenceRequiredViewRequest) returns (RpcShowPreferenceRequiredViewResponse);
|
||||
}
|
||||
|
||||
message RpcShowWindowRequest {
|
||||
|
|
@ -31,6 +32,16 @@ message RpcClearInlineViewRequest {
|
|||
message RpcClearInlineViewResponse {
|
||||
}
|
||||
|
||||
message RpcShowPreferenceRequiredViewRequest {
|
||||
string plugin_id = 1;
|
||||
string entrypoint_id = 2;
|
||||
bool plugin_preferences_required = 3;
|
||||
bool entrypoint_preferences_required = 4;
|
||||
}
|
||||
|
||||
message RpcShowPreferenceRequiredViewResponse {
|
||||
}
|
||||
|
||||
|
||||
enum RpcRenderLocation {
|
||||
INLINE_VIEW_LOCATION = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue