diff --git a/cosmic-applet-bluetooth/i18n/en/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/en/cosmic_applet_bluetooth.ftl index 378a87ec..d9e98b67 100644 --- a/cosmic-applet-bluetooth/i18n/en/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/en/cosmic_applet_bluetooth.ftl @@ -7,4 +7,6 @@ confirm = Confirm cancel = Cancel unsuccessful = Pairing Unsuccessful check-device = Make sure {$deviceName} is turned on, in range, and is ready to pair. -try-again = Try Again \ No newline at end of file +try-again = Try Again +discoverable = Discoverable +pairable = Pairable \ No newline at end of file diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index 13e2e99d..884a5fec 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -34,19 +34,6 @@ pub fn run() -> cosmic::iced::Result { CosmicBluetoothApplet::run(helper.window_settings()) } -// impl Into<()> for NewConnectionState { -// fn into(self) -> AccessPoint { -// match self { -// NewConnectionState::EnterPassword { -// access_point, -// password, -// } => access_point, -// NewConnectionState::Waiting(access_point) => access_point, -// NewConnectionState::Failure(access_point) => access_point, -// } -// } -// } - #[derive(Default)] struct CosmicBluetoothApplet { icon_name: String, @@ -151,9 +138,6 @@ impl Application for CosmicBluetoothApplet { BluerRequest::StateUpdate if self.popup.is_some() && self.bluer_sender.is_some() => { - for device in &self.bluer_state.devices { - dbg!((&device.name, &device.status)); - } let tx = self.bluer_sender.as_ref().cloned().unwrap(); return Command::perform( async move { @@ -172,9 +156,6 @@ impl Application for CosmicBluetoothApplet { self.bluer_state = state; } BluerEvent::DevicesChanged { state } => { - for device in &state.devices { - dbg!(&device.name); - } self.bluer_state = state; } BluerEvent::Finished => { @@ -372,12 +353,22 @@ impl Application for CosmicBluetoothApplet { } let mut content = column![ - container( + column![ toggler(fl!("bluetooth"), self.bluer_state.bluetooth_enabled, |m| { Message::Request(BluerRequest::SetBluetoothEnabled(m)) },) + .width(Length::Fill), + // these are not in the UX mockup, but they are useful imo + toggler(fl!("discoverable"), self.bluer_state.discoverable, |m| { + Message::Request(BluerRequest::SetDiscoverable(m)) + },) + .width(Length::Fill), + toggler(fl!("pairable"), self.bluer_state.pairable, |m| { + Message::Request(BluerRequest::SetPairable(m)) + },) .width(Length::Fill) - ) + ] + .spacing(8) .padding([0, 12]), divider::horizontal::light(), known_bluetooth, diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index de83dc33..0b813a46 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -67,10 +67,7 @@ async fn start_listening(id: I, state: State) -> (Option<(I, Bl let event = if let Some(event) = session_rx.recv().await { match event { BluerSessionEvent::ChangesProcessed(state) => { - return ( - Some((id, BluerEvent::DevicesChanged { state })), - State::Waiting { session_state }, - ); + Some((id, BluerEvent::DevicesChanged { state })) } BluerSessionEvent::RequestResponse { req, @@ -90,7 +87,6 @@ async fn start_listening(id: I, state: State) -> (Option<(I, Bl } else { return (None, State::Finished); }; - session_state.rx = Some(session_rx); (event, State::Waiting { session_state }) } @@ -101,6 +97,8 @@ async fn start_listening(id: I, state: State) -> (Option<(I, Bl #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub enum BluerRequest { SetBluetoothEnabled(bool), + SetPairable(bool), + SetDiscoverable(bool), PairDevice(Address), ConnectDevice(Address), DisconnectDevice(Address), @@ -130,6 +128,8 @@ pub enum BluerEvent { pub struct BluerState { pub devices: Vec, pub bluetooth_enabled: bool, + pub discoverable: bool, + pub pairable: bool, } #[derive(Debug, Clone)] @@ -178,6 +178,7 @@ impl BluerDevice { } } +#[derive(Debug, Clone)] pub enum BluerSessionEvent { RequestResponse { req: BluerRequest, @@ -334,7 +335,6 @@ impl BluerSessionState { )) .await; let res = rx.recv().await; - dbg!(res); match res { Some(res) if res => Ok(()), _ => Err(bluer::agent::ReqError::Rejected), @@ -404,8 +404,9 @@ impl BluerSessionState { tx, active_requests: Arc::new(Mutex::new(HashMap::new())), }; - self_.process_changes(); self_.process_requests(request_rx); + self_.process_changes(); + Ok(self_) } @@ -433,7 +434,15 @@ impl BluerSessionState { let _ = tx .send(BluerSessionEvent::ChangesProcessed(BluerState { devices: build_device_list(&adapter_clone).await, - bluetooth_enabled: true, + bluetooth_enabled: adapter_clone + .is_powered() + .await + .unwrap_or_default(), + discoverable: adapter_clone + .is_discoverable() + .await + .unwrap_or_default(), + pairable: adapter_clone.is_pairable().await.unwrap_or_default(), })) .await; // reset timeout @@ -518,11 +527,25 @@ impl BluerSessionState { } } BluerRequest::StateUpdate => {} + BluerRequest::SetPairable(enabled) => { + let res = adapter_clone.set_pairable(*enabled).await; + if let Err(e) = res { + err_msg = Some(e.to_string()); + } + } + BluerRequest::SetDiscoverable(enabled) => { + let res = adapter_clone.set_discoverable(*enabled).await; + if let Err(e) = res { + err_msg = Some(e.to_string()); + } + } }; let state = BluerState { devices: build_device_list(&adapter_clone).await, bluetooth_enabled: adapter_clone.is_powered().await.unwrap_or_default(), + discoverable: adapter_clone.is_discoverable().await.unwrap_or_default(), + pairable: adapter_clone.is_pairable().await.unwrap_or_default(), }; let _ = tx_clone @@ -550,6 +573,8 @@ impl BluerSessionState { devices: build_device_list(&self.adapter).await, // TODO is this a proper way of checking if bluetooth is enabled? bluetooth_enabled: self.adapter.is_powered().await.unwrap_or_default(), + discoverable: self.adapter.is_discoverable().await.unwrap_or_default(), + pairable: self.adapter.is_pairable().await.unwrap_or_default(), } } }