use std::sync::Arc;
use toasty::Db;
use topcoat::{
Result,
context::Cx,
view::{BoxView, View, ViewExt},
};
use super::validation_cx;
use crate::{
bus::NotificationBus,
notification::Notifications,
panel::{
Panel,
state::{PanelState, current, enter},
},
resource::Mounts,
};
#[derive(Clone)]
pub struct PanelHandle {
pub(super) db: Db,
pub(super) mounts: Arc<Mounts>,
pub(super) panel: Option<Arc<PanelState>>,
pub(super) prefix: String,
pub(super) bus: NotificationBus,
}
impl PanelHandle {
pub fn context(&self) -> Cx {
validation_cx(&self.db, &self.mounts)
}
pub fn enter(&self, cx: &Cx) -> Cx {
match &self.panel {
Some(panel) => enter(cx, panel),
None => cx.with(EnteredPanel(Arc::clone(&self.mounts))),
}
}
pub fn url(&self) -> Option<String> {
self.panel.as_ref().map(|panel| panel.realm.prefix.clone())
}
pub fn notifications(&self) -> Notifications {
Notifications::new(self.db.clone(), self.bus.clone(), self.prefix.clone(), None)
}
pub async fn document<'a>(
&'a self,
cx: &'a Cx,
title: impl Into<String>,
body: impl View + 'a,
) -> Result<BoxView<'a>> {
Panel::render_document(cx, self.panel.as_deref(), title.into(), body.boxed()).await
}
}
pub(super) struct EnteredPanel(Arc<Mounts>);
pub(super) fn request_mounts(cx: &Cx) -> Option<&Mounts> {
match current(cx) {
Some(panel) => Some(&*panel.mounts),
None => topcoat::context::try_request_context::<EnteredPanel>(cx)
.map(|EnteredPanel(mounts)| &**mounts),
}
}