feat(bluetooth): add discoverable & pairable toggles + fix bug where the receiver for bluetooth events is accidentally dropped
This commit is contained in:
parent
c068343c4d
commit
b1a5468547
3 changed files with 48 additions and 30 deletions
|
|
@ -8,3 +8,5 @@ cancel = Cancel
|
||||||
unsuccessful = Pairing Unsuccessful
|
unsuccessful = Pairing Unsuccessful
|
||||||
check-device = Make sure {$deviceName} is turned on, in range, and is ready to pair.
|
check-device = Make sure {$deviceName} is turned on, in range, and is ready to pair.
|
||||||
try-again = Try Again
|
try-again = Try Again
|
||||||
|
discoverable = Discoverable
|
||||||
|
pairable = Pairable
|
||||||
|
|
@ -34,19 +34,6 @@ pub fn run() -> cosmic::iced::Result {
|
||||||
CosmicBluetoothApplet::run(helper.window_settings())
|
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)]
|
#[derive(Default)]
|
||||||
struct CosmicBluetoothApplet {
|
struct CosmicBluetoothApplet {
|
||||||
icon_name: String,
|
icon_name: String,
|
||||||
|
|
@ -151,9 +138,6 @@ impl Application for CosmicBluetoothApplet {
|
||||||
BluerRequest::StateUpdate
|
BluerRequest::StateUpdate
|
||||||
if self.popup.is_some() && self.bluer_sender.is_some() =>
|
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();
|
let tx = self.bluer_sender.as_ref().cloned().unwrap();
|
||||||
return Command::perform(
|
return Command::perform(
|
||||||
async move {
|
async move {
|
||||||
|
|
@ -172,9 +156,6 @@ impl Application for CosmicBluetoothApplet {
|
||||||
self.bluer_state = state;
|
self.bluer_state = state;
|
||||||
}
|
}
|
||||||
BluerEvent::DevicesChanged { state } => {
|
BluerEvent::DevicesChanged { state } => {
|
||||||
for device in &state.devices {
|
|
||||||
dbg!(&device.name);
|
|
||||||
}
|
|
||||||
self.bluer_state = state;
|
self.bluer_state = state;
|
||||||
}
|
}
|
||||||
BluerEvent::Finished => {
|
BluerEvent::Finished => {
|
||||||
|
|
@ -372,12 +353,22 @@ impl Application for CosmicBluetoothApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut content = column![
|
let mut content = column![
|
||||||
container(
|
column![
|
||||||
toggler(fl!("bluetooth"), self.bluer_state.bluetooth_enabled, |m| {
|
toggler(fl!("bluetooth"), self.bluer_state.bluetooth_enabled, |m| {
|
||||||
Message::Request(BluerRequest::SetBluetoothEnabled(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)
|
.width(Length::Fill)
|
||||||
)
|
]
|
||||||
|
.spacing(8)
|
||||||
.padding([0, 12]),
|
.padding([0, 12]),
|
||||||
divider::horizontal::light(),
|
divider::horizontal::light(),
|
||||||
known_bluetooth,
|
known_bluetooth,
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,7 @@ async fn start_listening<I: Copy + Debug>(id: I, state: State) -> (Option<(I, Bl
|
||||||
let event = if let Some(event) = session_rx.recv().await {
|
let event = if let Some(event) = session_rx.recv().await {
|
||||||
match event {
|
match event {
|
||||||
BluerSessionEvent::ChangesProcessed(state) => {
|
BluerSessionEvent::ChangesProcessed(state) => {
|
||||||
return (
|
Some((id, BluerEvent::DevicesChanged { state }))
|
||||||
Some((id, BluerEvent::DevicesChanged { state })),
|
|
||||||
State::Waiting { session_state },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
BluerSessionEvent::RequestResponse {
|
BluerSessionEvent::RequestResponse {
|
||||||
req,
|
req,
|
||||||
|
|
@ -90,7 +87,6 @@ async fn start_listening<I: Copy + Debug>(id: I, state: State) -> (Option<(I, Bl
|
||||||
} else {
|
} else {
|
||||||
return (None, State::Finished);
|
return (None, State::Finished);
|
||||||
};
|
};
|
||||||
|
|
||||||
session_state.rx = Some(session_rx);
|
session_state.rx = Some(session_rx);
|
||||||
(event, State::Waiting { session_state })
|
(event, State::Waiting { session_state })
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +97,8 @@ async fn start_listening<I: Copy + Debug>(id: I, state: State) -> (Option<(I, Bl
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||||
pub enum BluerRequest {
|
pub enum BluerRequest {
|
||||||
SetBluetoothEnabled(bool),
|
SetBluetoothEnabled(bool),
|
||||||
|
SetPairable(bool),
|
||||||
|
SetDiscoverable(bool),
|
||||||
PairDevice(Address),
|
PairDevice(Address),
|
||||||
ConnectDevice(Address),
|
ConnectDevice(Address),
|
||||||
DisconnectDevice(Address),
|
DisconnectDevice(Address),
|
||||||
|
|
@ -130,6 +128,8 @@ pub enum BluerEvent {
|
||||||
pub struct BluerState {
|
pub struct BluerState {
|
||||||
pub devices: Vec<BluerDevice>,
|
pub devices: Vec<BluerDevice>,
|
||||||
pub bluetooth_enabled: bool,
|
pub bluetooth_enabled: bool,
|
||||||
|
pub discoverable: bool,
|
||||||
|
pub pairable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -178,6 +178,7 @@ impl BluerDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum BluerSessionEvent {
|
pub enum BluerSessionEvent {
|
||||||
RequestResponse {
|
RequestResponse {
|
||||||
req: BluerRequest,
|
req: BluerRequest,
|
||||||
|
|
@ -334,7 +335,6 @@ impl BluerSessionState {
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
let res = rx.recv().await;
|
let res = rx.recv().await;
|
||||||
dbg!(res);
|
|
||||||
match res {
|
match res {
|
||||||
Some(res) if res => Ok(()),
|
Some(res) if res => Ok(()),
|
||||||
_ => Err(bluer::agent::ReqError::Rejected),
|
_ => Err(bluer::agent::ReqError::Rejected),
|
||||||
|
|
@ -404,8 +404,9 @@ impl BluerSessionState {
|
||||||
tx,
|
tx,
|
||||||
active_requests: Arc::new(Mutex::new(HashMap::new())),
|
active_requests: Arc::new(Mutex::new(HashMap::new())),
|
||||||
};
|
};
|
||||||
self_.process_changes();
|
|
||||||
self_.process_requests(request_rx);
|
self_.process_requests(request_rx);
|
||||||
|
self_.process_changes();
|
||||||
|
|
||||||
Ok(self_)
|
Ok(self_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -433,7 +434,15 @@ impl BluerSessionState {
|
||||||
let _ = tx
|
let _ = tx
|
||||||
.send(BluerSessionEvent::ChangesProcessed(BluerState {
|
.send(BluerSessionEvent::ChangesProcessed(BluerState {
|
||||||
devices: build_device_list(&adapter_clone).await,
|
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;
|
.await;
|
||||||
// reset timeout
|
// reset timeout
|
||||||
|
|
@ -518,11 +527,25 @@ impl BluerSessionState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BluerRequest::StateUpdate => {}
|
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 {
|
let state = BluerState {
|
||||||
devices: build_device_list(&adapter_clone).await,
|
devices: build_device_list(&adapter_clone).await,
|
||||||
bluetooth_enabled: adapter_clone.is_powered().await.unwrap_or_default(),
|
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
|
let _ = tx_clone
|
||||||
|
|
@ -550,6 +573,8 @@ impl BluerSessionState {
|
||||||
devices: build_device_list(&self.adapter).await,
|
devices: build_device_list(&self.adapter).await,
|
||||||
// TODO is this a proper way of checking if bluetooth is enabled?
|
// TODO is this a proper way of checking if bluetooth is enabled?
|
||||||
bluetooth_enabled: self.adapter.is_powered().await.unwrap_or_default(),
|
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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue