Mountain/Environment/WebviewProvider/
Lifecycle.rs1use CommonLibrary::{
9 Error::CommonError::CommonError,
10 Webview::DTO::WebviewContentOptionsDTO::WebviewContentOptionsDTO,
11};
12use serde_json::{Value, json};
13use tauri::{Emitter, Manager, WebviewWindowBuilder};
14use uuid::Uuid;
15
16use super::super::{MountainEnvironment::MountainEnvironment, Utility};
17use crate::{ApplicationState::DTO::WebviewStateDTO::WebviewStateDTO, dev_log};
18
19pub(super) async fn create_webview_panel_impl(
21 env:&MountainEnvironment,
22 extension_data_value:Value,
23 view_type:String,
24 title:String,
25 _show_options_value:Value,
26 panel_options_value:Value,
27 content_options_value:Value,
28) -> Result<String, CommonError> {
29 let handle = Uuid::new_v4().to_string();
30
31 dev_log!(
32 "extensions",
33 "[WebviewProvider] Creating WebviewPanel with handle: {}, viewType: {}",
34 handle,
35 view_type
36 );
37
38 let content_options:WebviewContentOptionsDTO =
40 serde_json::from_value(content_options_value.clone()).map_err(|error| {
41 CommonError::InvalidArgument { ArgumentName:"ContentOptions".into(), Reason:error.to_string() }
42 })?;
43
44 let state = WebviewStateDTO {
45 Handle:handle.clone(),
46 ViewType:view_type.clone(),
47 Title:title.clone(),
48 ContentOptions:content_options,
49 PanelOptions:panel_options_value.clone(),
50 SideCarIdentifier:"cocoon-main".to_string(),
51 ExtensionIdentifier:extension_data_value
52 .get("id")
53 .and_then(|v| v.as_str())
54 .unwrap_or_default()
55 .to_string(),
56 IsActive:true,
57 IsVisible:true,
58 };
59
60 {
62 let mut webview_guard = env
63 .ApplicationState
64 .Feature
65 .Webviews
66 .ActiveWebviews
67 .lock()
68 .map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
69
70 webview_guard.insert(handle.clone(), state);
71 }
72
73 let title_clone = title.clone();
75 let _webview_window = WebviewWindowBuilder::new(
76 &env.ApplicationHandle,
77 &handle,
78 tauri::WebviewUrl::App("WebviewHost.html".into()),
79 )
80 .title(title)
81 .initialization_script(&format!(
82 "window.__WEBVIEW_INITIAL_STATE__ = {};",
83 json!({
84 "Handle": handle,
85 "ViewType": view_type,
86 "Title": title_clone
87 })
88 ))
89 .build()
90 .map_err(|error| {
91 dev_log!(
92 "extensions",
93 "error: [WebviewProvider] Failed to create Webview window: {}",
94 error
95 );
96 CommonError::UserInterfaceInteraction { Reason:error.to_string() }
97 })?;
98
99 crate::Environment::WebviewProvider::Messaging::setup_webview_message_listener_impl(env, handle.clone()).await?;
101
102 env.ApplicationHandle
104 .emit::<Value>(
105 "sky://webview/created",
106 json!({ "Handle": handle.clone(), "ViewType": view_type.clone(), "Title": title_clone }),
107 )
108 .map_err(|error| {
109 CommonError::IPCError { Description:format!("Failed to emit Webview creation event: {}", error) }
110 })?;
111
112 Ok(handle)
113}
114
115pub(super) async fn dispose_webview_panel_impl(env:&MountainEnvironment, handle:String) -> Result<(), CommonError> {
117 dev_log!("extensions", "[WebviewProvider] Disposing WebviewPanel: {}", handle);
118
119 let _ = crate::Environment::WebviewProvider::Messaging::remove_webview_message_listener_impl(env, &handle).await;
121
122 if let Some(webview_window) = env.ApplicationHandle.get_webview_window(&handle) {
124 if let Err(error) = webview_window.close() {
125 dev_log!(
126 "extensions",
127 "warn: [WebviewProvider] Failed to close Webview window: {}",
128 error
129 );
130 }
131 }
132
133 env.ApplicationState
135 .Feature
136 .Webviews
137 .ActiveWebviews
138 .lock()
139 .map_err(Utility::MapApplicationStateLockErrorToCommonError)?
140 .remove(&handle);
141
142 env.ApplicationHandle
144 .emit::<Value>("sky://webview/disposed", json!({ "Handle": handle }))
145 .map_err(|error| {
146 CommonError::IPCError { Description:format!("Failed to emit Webview disposal event: {}", error) }
147 })?;
148
149 Ok(())
150}
151
152pub(super) async fn reveal_webview_panel_impl(
154 env:&MountainEnvironment,
155 handle:String,
156 _show_options_value:Value,
157) -> Result<(), CommonError> {
158 dev_log!("extensions", "[WebviewProvider] Revealing WebviewPanel: {}", handle);
159
160 if let Some(webview_window) = env.ApplicationHandle.get_webview_window(&handle) {
161 webview_window.show().map_err(|error| {
162 CommonError::UserInterfaceInteraction { Reason:format!("Failed to show Webview window: {}", error) }
163 })?;
164
165 webview_window.set_focus().map_err(|error| {
166 CommonError::UserInterfaceInteraction { Reason:format!("Failed to focus Webview window: {}", error) }
167 })?;
168
169 {
171 let mut webview_guard = env
172 .ApplicationState
173 .Feature
174 .Webviews
175 .ActiveWebviews
176 .lock()
177 .map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
178
179 if let Some(state) = webview_guard.get_mut(&handle) {
180 state.IsVisible = true;
181 }
182 }
183
184 env.ApplicationHandle
186 .emit::<Value>("sky://webview/revealed", json!({ "Handle": handle }))
187 .map_err(|error| {
188 CommonError::IPCError { Description:format!("Failed to emit Webview revealed event: {}", error) }
189 })?;
190 }
191
192 Ok(())
193}