Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
TreeView.rs

1//! Effect constructors for tree-view registration and disposal from the
2//! Cocoon extension host. Delegates to `TreeViewProvider` on
3//! `MountainEnvironment` and emits `SkyEvent` notifications to keep the
4//! Sky workbench's `ITreeView` instances in sync.
5
6use std::sync::Arc;
7
8use CommonLibrary::{
9	Environment::Requires::Requires,
10	IPC::SkyEvent::SkyEvent,
11	TreeView::TreeViewProvider::TreeViewProvider,
12};
13use serde_json::{Value, json};
14use tauri::Runtime;
15
16use crate::{
17	IPC::SkyEmit::LogSkyEmit,
18	RunTime::ApplicationRunTime::ApplicationRunTime,
19	Track::Effect::{
20		CreateEffectForRequest::Utilities::Params::{str_at, string_at, val_at},
21		MappedEffectType::MappedEffect,
22	},
23	dev_log,
24};
25
26pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
27	match MethodName {
28		"$tree:register" | "tree.register" => {
29			crate::effect!(run_time, {
30				let provider:Arc<dyn TreeViewProvider> = run_time.Environment.Require();
31
32				let first = str_at(&Parameters, 0);
33
34				let (ViewId, Options) = if Parameters.get(2).is_some() {
35					let vid = Parameters.get(1).and_then(Value::as_str).unwrap_or(first).to_string();
36
37					let opts = val_at(&Parameters, 2);
38
39					(vid, opts)
40				} else {
41					let vid = first.to_string();
42
43					let opts = val_at(&Parameters, 1);
44
45					(vid, opts)
46				};
47
48				dev_log!("tree-view", "[TreeView] register view={}", ViewId);
49
50				let Result = provider.RegisterTreeDataProvider(ViewId.clone(), Options.clone()).await;
51
52				dev_log!(
53					"tree-view",
54					"[TreeView] register view={} result={}",
55					ViewId,
56					if Result.is_ok() { "ok" } else { "err" }
57				);
58
59				if Result.is_ok() {
60					if let Err(Error) = LogSkyEmit(
61						&run_time.Environment.ApplicationHandle,
62						SkyEvent::TreeViewCreate.AsStr(),
63						json!({ "viewId": ViewId, "options": Options }),
64					) {
65						dev_log!("tree-view", "warn: [TreeView] emit failed view={}: {}", ViewId, Error);
66					}
67				}
68
69				Result.map(|_| json!(null)).map_err(|E| E.to_string())
70			})
71		},
72
73		"tree.unregister" | "tree.dispose" => {
74			crate::effect!(run_time, {
75				let ViewId = string_at(&Parameters, 0);
76
77				if ViewId.is_empty() {
78					return Ok(json!(null));
79				}
80
81				dev_log!("tree-view", "[TreeView] unregister view={}", ViewId);
82
83				let provider:Arc<dyn TreeViewProvider> = run_time.Environment.Require();
84
85				let Result = provider.UnregisterTreeDataProvider(ViewId.clone()).await;
86
87				if Result.is_ok() {
88					if let Err(Error) = LogSkyEmit(
89						&run_time.Environment.ApplicationHandle,
90						SkyEvent::TreeViewDispose.AsStr(),
91						json!({ "viewId": ViewId }),
92					) {
93						dev_log!("tree-view", "warn: [TreeView] dispose emit failed view={}: {}", ViewId, Error);
94					}
95				}
96
97				Result.map(|_| json!(null)).map_err(|E| E.to_string())
98			})
99		},
100
101		// `treeView.reveal(element, options)` - extension asks Mountain to
102		// scroll the native panel to a specific tree item. Previously only
103		// existed in the Tauri IPC path (mod.rs), so Cocoon's gRPC
104		// sendRequest("tree.reveal", ...) fell through to "Unknown method".
105		"tree.reveal" => {
106			crate::effect!(run_time, {
107				let Payload = if Parameters.is_object() {
108					Parameters.clone()
109				} else {
110					json!({
111						"viewId": val_at(&Parameters, 0),
112						"element": val_at(&Parameters, 1),
113						"options": val_at(&Parameters, 2),
114					})
115				};
116
117				if let Err(Error) =
118					LogSkyEmit(&run_time.Environment.ApplicationHandle, "sky://tree-view/reveal", Payload)
119				{
120					dev_log!("tree-view", "warn: [TreeView] reveal emit failed: {}", Error);
121				}
122
123				Ok(json!(null))
124			})
125		},
126
127		_ => None,
128	}
129}