ftml_viewer_components/
config.rs

1use flams_ontology::uris::{DocumentElementURI, NarrativeURI, URI};
2use ftml_extraction::open::terms::VarOrSym;
3use leptos::prelude::*;
4
5pub struct FTMLConfiguration {
6    pub allow_hovers: Option<bool>,
7    pub top_uri: Option<NarrativeURI>,
8    // on_section_title: Option<OnSectionTitle>,
9    // on_fragment: Option<FragmentContinuation>,
10    // on_inpuref: Option<InputRefContinuation>,
11    // problem_opts: Option<ProblemOptions>,
12}
13
14#[derive(Debug, Clone)]
15pub(crate) struct IdPrefix(pub String);
16impl IdPrefix {
17    pub fn new_id(self, s: &str) -> String {
18        if self.0.is_empty() {
19            s.to_string()
20        } else {
21            format!("{}/{s}", self.0)
22        }
23    }
24}
25
26#[derive(Clone)]
27pub(crate) struct FTMLConfig {
28    owner: Owner,
29    on_clicks: StoredValue<flams_utils::prelude::HMap<VarOrSym, RwSignal<bool>>>,
30    #[cfg(feature = "omdoc")]
31    forced_notations:
32        StoredValue<flams_utils::prelude::HMap<URI, RwSignal<Option<DocumentElementURI>>>>,
33}
34
35impl FTMLConfig {
36    pub fn new() -> Self {
37        let owner = Owner::new(); //current().expect("Something went horribly wrong");
38        Self {
39            owner,
40            on_clicks: StoredValue::new(flams_utils::prelude::HMap::default()),
41            #[cfg(feature = "omdoc")]
42            forced_notations: StoredValue::new(flams_utils::prelude::HMap::default()),
43        }
44    }
45
46    pub fn do_in<R>(&self, f: impl FnOnce() -> R) -> R {
47        self.owner.clone().with(f)
48    }
49
50    pub fn get_on_click(&self, uri: &VarOrSym) -> RwSignal<bool> {
51        use crate::components::terms::do_onclick;
52        use thaw::{Dialog, DialogSurface};
53        if let Some(s) = self.on_clicks.with_value(|map| map.get(uri).copied()) {
54            return s;
55        }
56        self.owner.with(move || {
57            let signal = RwSignal::new(false);
58            let uri = uri.clone();
59            self.on_clicks.update_value(|map| {
60                map.insert(uri.clone(), signal);
61            });
62            let _ = view! {<Dialog open=signal><DialogSurface>{
63                do_onclick(uri)
64            }</DialogSurface></Dialog>};
65            signal
66        })
67    }
68}
69
70#[cfg(feature = "omdoc")]
71impl FTMLConfig {
72    pub fn get_forced_notation(&self, uri: &URI) -> RwSignal<Option<DocumentElementURI>> {
73        self.owner.with(|| {
74            self.forced_notations
75                .with_value(|map| map.get(uri).copied())
76                .unwrap_or_else(|| {
77                    #[cfg(any(feature = "csr", feature = "hydrate"))]
78                    let sig = {
79                        use gloo_storage::Storage;
80                        let s = gloo_storage::LocalStorage::get(format!("notation_{uri}"))
81                            .map_or_else(
82                                |_| RwSignal::new(None),
83                                |v: DocumentElementURI| {
84                                    let uri = uri.clone();
85                                    let sig = RwSignal::new(None);
86                                    let _ = Resource::new(
87                                        || (),
88                                        move |()| {
89                                            let uri = uri.clone();
90                                            let v = v.clone();
91                                            async move {
92                                                let _ = crate::remote::server_config
93                                                    .notations(uri)
94                                                    .await;
95                                                sig.set(Some(v));
96                                            }
97                                        },
98                                    );
99                                    sig
100                                },
101                            );
102                        let uri = uri.clone();
103                        Effect::new(move || {
104                            s.with(|s| {
105                                if let Some(s) = s.as_ref() {
106                                    let _ = gloo_storage::LocalStorage::set(
107                                        format!("notation_{uri}"),
108                                        &s,
109                                    );
110                                } else {
111                                    let _ = gloo_storage::LocalStorage::delete(format!(
112                                        "notation_{uri}"
113                                    ));
114                                }
115                            });
116                        });
117                        s
118                    };
119                    #[cfg(not(any(feature = "csr", feature = "hydrate")))]
120                    let sig = RwSignal::new(None);
121                    self.forced_notations.update_value(|map| {
122                        map.insert(uri.clone(), sig);
123                    });
124                    sig
125                })
126        })
127    }
128}