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