Mountain/Track/Effect/CreateEffectForRequest/
WindowUI.rs1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3use std::{future::Future, pin::Pin, sync::Arc};
9
10use serde_json::{Value, json};
11use tauri::Runtime;
12
13use crate::{
14 ApplicationState::State::ApplicationState::ApplicationState,
15 RunTime::ApplicationRunTime::ApplicationRunTime,
16 Track::Effect::MappedEffectType::MappedEffect,
17 dev_log,
18};
19
20pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
21 match MethodName {
22 "Window.ShowMessage" => {
23 let effect =
24 move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
25 Box::pin(async move {
26 use tauri::Emitter;
27 let AppHandle = run_time.Environment.ApplicationHandle.clone();
28 let Payload = if Parameters.is_array() {
29 Parameters.get(0).cloned().unwrap_or_default()
30 } else {
31 Parameters
32 };
33 let Id = format!(
34 "notification-{}",
35 std::time::SystemTime::now()
36 .duration_since(std::time::UNIX_EPOCH)
37 .map(|D| D.as_millis())
38 .unwrap_or(0)
39 );
40 let Message = Payload.get("message").and_then(Value::as_str).unwrap_or("").to_string();
41 let Level = Payload.get("level").and_then(Value::as_str).unwrap_or("info").to_string();
42 let Items = Payload.get("items").cloned().unwrap_or(json!([]));
43 let Options = Payload.get("options").cloned().unwrap_or(json!({}));
44 if let Err(Error) = AppHandle.emit(
45 "sky://notification/show",
46 json!({
47 "id": Id,
48 "message": Message,
49 "severity": Level,
50 "actions": Items,
51 "options": Options,
52 }),
53 ) {
54 dev_log!(
55 "notification",
56 "warn: [Window.ShowMessage] sky://notification/show emit failed: {}",
57 Error
58 );
59 }
60 Ok(Value::Null)
61 })
62 };
63
64 Some(Ok(Box::new(effect)))
65 },
66
67 "Window.ShowQuickPick" | "Window.ShowInputBox" | "Window.ShowOpenDialog" | "Window.ShowSaveDialog" => {
68 let MethodNameOwned = MethodName.to_string();
69
70 let effect =
71 move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
72 Box::pin(async move {
73 use tauri::Emitter;
74
75 let Args = if Parameters.is_array() { Parameters } else { json!([Parameters]) };
76
77 let Channel = match MethodNameOwned.as_str() {
78 "Window.ShowQuickPick" => "sky://quickpick/show",
79 "Window.ShowInputBox" => "sky://input-box/show",
80 "Window.ShowOpenDialog" => "sky://dialog/open",
81 "Window.ShowSaveDialog" => "sky://dialog/save",
82 _ => "sky://quickpick/show",
83 };
84
85 let Nonce = format!(
86 "ui-{}",
87 std::time::SystemTime::now()
88 .duration_since(std::time::UNIX_EPOCH)
89 .map(|D| D.as_nanos())
90 .unwrap_or(0)
91 );
92
93 let (tx, rx) = tokio::sync::oneshot::channel();
96 run_time.Environment.ApplicationState.UI.AddPendingRequest(Nonce.clone(), tx);
97
98 let AppHandle = run_time.Environment.ApplicationHandle.clone();
99 if let Err(Error) = AppHandle.emit(Channel, json!({ "nonce": Nonce, "args": Args })) {
100 run_time.Environment.ApplicationState.UI.RemovePendingRequest(&Nonce.clone());
103 dev_log!("ipc", "warn: [{}] {} emit failed: {}", MethodNameOwned, Channel, Error);
104 return Err(format!("[{}] emit failed: {}", MethodNameOwned, Error));
105 }
106
107 match rx.await {
111 Ok(Ok(Value)) => Ok(Value),
112 Ok(Err(CommonError)) => Err(CommonError.to_string()),
113 Err(_RecvError) => {
114 dev_log!("ipc", "[{}] dialog dismissed (nonce dropped)", MethodNameOwned);
119 Ok(Value::Null)
120 },
121 }
122 })
123 };
124
125 Some(Ok(Box::new(effect)))
126 },
127
128 _ => None,
129 }
130}