Mountain/Track/Effect/CreateEffectForRequest/
Webview.rs1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3use std::{future::Future, pin::Pin, sync::Arc};
27
28use CommonLibrary::{CustomEditor::CustomEditorProvider::CustomEditorProvider, Environment::Requires::Requires};
29use serde_json::{Value, json};
30use tauri::Runtime;
31use url::Url;
32
33use crate::{
34 IPC::SkyEmit::LogSkyEmit,
35 RunTime::ApplicationRunTime::ApplicationRunTime,
36 Track::Effect::MappedEffectType::MappedEffect,
37 dev_log,
38};
39
40pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
41 match MethodName {
42 "$webview:create"
43 | "webview.create"
44 | "webview.setHtml"
45 | "webview.setOptions"
46 | "webview.postMessage"
47 | "webview.reveal"
48 | "webview.dispose"
49 | "webview.registerView"
50 | "webview.unregisterView"
51 | "webview.registerCustomEditor"
52 | "webview.unregisterCustomEditor" => {
53 dev_log!("ipc", "[WebviewEffect] dispatch-enter method={}", MethodName);
54
55 let Method = MethodName.to_string();
56
57 let effect =
58 move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
59 let Method = Method.clone();
60
61 Box::pin(async move {
62 let RawSuffix = Method.trim_start_matches("$webview:").trim_start_matches("webview.");
63 let Suffix:&str = match RawSuffix {
64 "setHtml" => "set-html",
65 "postMessage" => "post-message",
66 Other => Other,
67 };
68 let Payload:Value = if Parameters.is_object() {
69 Parameters.clone()
70 } else if let Some(First) = Parameters.get(0) {
71 if First.is_object() {
72 First.clone()
73 } else {
74 let mut Object = serde_json::Map::new();
75 Object.insert("method".to_string(), Value::String(Method.clone()));
76 Object.insert("handle".to_string(), First.clone());
77 Object.insert("args".to_string(), Parameters.clone());
78 if let Some(Second) = Parameters.get(1) {
79 let Alias = match Method.as_str() {
80 "webview.setHtml" => "html",
81 "webview.postMessage" => "message",
82 "webview.registerView" | "webview.unregisterView" => "viewId",
83 "webview.registerCustomEditor"
84 | "webview.unregisterCustomEditor"
85 | "webview.create" => "viewType",
86 _ => "value",
87 };
88 Object.insert(Alias.to_string(), Second.clone());
89 if Method.as_str() == "webview.create" {
90 if let Some(Third) = Parameters.get(2) {
91 Object.insert("title".to_string(), Third.clone());
92 }
93 }
94 }
95 Value::Object(Object)
96 }
97 } else {
98 json!({
99 "method": Method,
100 "handle": Parameters.clone(),
101 })
102 };
103 let EventName = format!("sky://webview/{}", Suffix);
104 if let Err(Error) = LogSkyEmit(&run_time.Environment.ApplicationHandle, &EventName, &Payload) {
105 dev_log!("ipc", "warn: [WebviewEffect] emit {} failed: {}", EventName, Error);
106 }
107 Ok(json!(null))
108 })
109 };
110
111 Some(Ok(Box::new(effect)))
112 },
113
114 "$resolveCustomEditor" => {
115 let effect =
116 move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
117 Box::pin(async move {
118 let provider:Arc<dyn CustomEditorProvider> = run_time.Environment.Require();
119 let view_type = Parameters.get(0).and_then(Value::as_str).unwrap_or("").to_string();
120 let resource_uri_str = Parameters.get(1).and_then(Value::as_str).unwrap_or("");
121 if resource_uri_str.is_empty() {
130 dev_log!(
131 "grpc",
132 "warn: [$resolveCustomEditor] empty resource URI view_type={}",
133 view_type
134 );
135 return Err(format!(
136 "$resolveCustomEditor: empty resource URI for view_type={}",
137 view_type
138 ));
139 }
140 let resource_uri = match Url::parse(resource_uri_str) {
141 Ok(u) => u,
142 Err(parse_err) => {
143 dev_log!(
144 "grpc",
145 "warn: [$resolveCustomEditor] invalid URI uri={} err={} view_type={}",
146 resource_uri_str,
147 parse_err,
148 view_type
149 );
150 return Err(format!(
151 "$resolveCustomEditor: invalid resource URI '{}': {}",
152 resource_uri_str, parse_err
153 ));
154 },
155 };
156 let webview_handle = Parameters.get(2).and_then(Value::as_str).unwrap_or("").to_string();
157 if webview_handle.is_empty() {
158 dev_log!(
159 "grpc",
160 "warn: [$resolveCustomEditor] empty webview handle uri={} view_type={}",
161 resource_uri_str,
162 view_type
163 );
164 return Err(format!(
165 "$resolveCustomEditor: empty webview handle for view_type={} uri={}",
166 view_type, resource_uri_str
167 ));
168 }
169 provider
170 .ResolveCustomEditor(view_type, resource_uri, webview_handle)
171 .await
172 .map(|_| json!(null))
173 .map_err(|e| e.to_string())
174 })
175 };
176
177 Some(Ok(Box::new(effect)))
178 },
179
180 _ => None,
181 }
182}