ftml_viewer_components/
config.rs1use 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 }
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(); 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}