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