hunk.code_window: 	});
   	useEffect(() => {
   		const onMouseDown = (e: MouseEvent) => {
   			e.stopPropagation();
  
hunk.labels: keep keep keep add keep
hunk.after_edit: 			if (os === 'browser') return;
  
hunk.file_path: interface/app/$libraryId/TopBar/NavigationButtons.tsx
hunk.type: add
file: use crate::api::notifications::Notification;
  
  use std::sync::{atomic::AtomicU32, Arc};
  
  use tokio::sync::broadcast;
  
  #[derive(Clone)]
  pub struct Notifications(
  	// Keep this private and use `Node::emit_notification` or `Library::emit_notification` instead.
  	broadcast::Sender<Notification>,
  	// Counter for `NotificationId::Node(_)`. NotificationId::Library(_, _)` is autogenerated by the DB.
  	Arc<AtomicU32>,
  );
  
  impl Notifications {
  	#[allow(clippy::new_without_default)]
  	pub fn new() -> Self {
  		let (tx, _) = broadcast::channel(30);
  		Self(tx, Arc::new(AtomicU32::new(0)))
  	}
  
  	pub fn subscribe(&self) -> broadcast::Receiver<Notification> {
  		self.0.subscribe()
  	}
  
  	/// DO NOT USE THIS. Use `Node::emit_notification` or `Library::emit_notification` instead.
  	pub fn _internal_send(&self, notif: Notification) {
  		self.0.send(notif).ok();
  	}
  
  	pub fn _internal_next_id(&self) -> u32 {
  		self.1.fetch_add(1, std::sync::atomic::Ordering::SeqCst)
  	}
  }
  