Give Bluetooth settings a bit of a refresh

It's now a bit more responsive to stuff happening, gives you more information, and remembers your previously paired devices for faster switching between them.
custom
jacqueline 10 months ago
parent a3eb2dd9dc
commit f78de39a75
  1. 42
      lua/settings.lua
  2. 9
      lua/widgets.lua
  3. 22
      src/drivers/bluetooth.cpp
  4. 2
      src/drivers/include/drivers/nvs.hpp
  5. 2
      src/drivers/nvs.cpp
  6. 5
      src/tangara/lua/property.cpp

@ -46,6 +46,7 @@ local BluetoothPairing = SettingsScreen:new {
for _, dev in pairs(devs) do
devices:add_btn(nil, dev.name):onClicked(function()
bluetooth.paired_device:set(dev)
backstack.pop()
end)
end
end)
@ -101,16 +102,15 @@ local BluetoothSettings = SettingsScreen:new {
theme.set_style(paired_label, "settings_title")
self.bindings = self.bindings + {
bluetooth.connected:bind(function(conn)
bluetooth.connecting:bind(function(conn)
if conn then
paired_label:set { text = "Connecting to:" }
else
if bluetooth.connected:get() then
paired_label:set { text = "Connected to:" }
else
paired_label:set { text = "Paired with:" }
end
end),
bluetooth.connecting:bind(function(conn)
if conn then
paired_label:set { text = "Connecting to:" }
end
end),
}
@ -159,22 +159,42 @@ local BluetoothSettings = SettingsScreen:new {
h = lvgl.SIZE_CONTENT,
}
-- 'Pair new device' button that goes to the discovery screen.
local button_container = self.content:Object {
w = lvgl.PCT(100),
h = lvgl.SIZE_CONTENT,
flex = {
flex_direction = "row",
justify_content = "center",
align_items = "space-evenly",
align_content = "center",
},
pad_top = 4,
pad_column = 4,
}
button_container:add_style(styles.list_item)
local pair_new = button_container:Button {}
pair_new:Label { text = "Pair new device" }
pair_new:onClicked(function()
backstack.push(BluetoothPairing:new())
end)
self.bindings = self.bindings + {
bluetooth.known_devices:bind(function(devs)
local group = lvgl.group.get_default()
group.remove_obj(pair_new)
devices:clean()
for _, dev in pairs(devs) do
devices:add_btn(nil, dev.name):onClicked(function()
bluetooth.paired_device:set(dev)
end)
end
group:add_obj(pair_new)
end)
}
local pair_new = self.content:Button {}
pair_new:Label { text = "Pair new device" }
pair_new:onClicked(function()
backstack.push(BluetoothPairing:new())
end)
end
}

@ -79,11 +79,10 @@ function widgets.Row(parent, left, right)
}
end
local bindings_meta = {
__add = function(a, b)
return table.move(a, 1, #a, #b + 1, b)
end
}
local bindings_meta = {}
bindings_meta["__add"] = function(a, b)
return setmetatable(table.move(a, 1, #a, #b + 1, b), bindings_meta)
end
function widgets.StatusBar(parent, opts)
local root = parent.root:Object {

@ -603,16 +603,21 @@ void Disabled::react(const events::Enable&) {
void Idle::entry() {
ESP_LOGI(kTag, "bt is idle");
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
}
void Idle::exit() {}
void Idle::exit() {
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
}
void Idle::react(const events::Disable& ev) {
transit<Disabled>();
}
void Idle::react(const events::PairedDeviceChanged& ev) {
if (sPairedWith_) {
connect(*sPairedWith_);
}
}
void Idle::react(events::internal::Gap ev) {
@ -633,18 +638,10 @@ void Connecting::entry() {
sTimeoutTimer = xTimerCreate("bt_timeout", pdMS_TO_TICKS(15000), false, NULL,
timeoutCallback);
xTimerStart(sTimeoutTimer, portMAX_DELAY);
if (sEventHandler_) {
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
}
}
void Connecting::exit() {
xTimerDelete(sTimeoutTimer, portMAX_DELAY);
if (sEventHandler_) {
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
}
}
void Connecting::react(const events::ConnectTimedOut& ev) {
@ -751,12 +748,16 @@ void Connected::entry() {
sStorage_->PreferredBluetoothDevice(sPairedWith_);
}
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
// TODO: if we already have a source, immediately start playing
}
void Connected::exit() {
ESP_LOGI(kTag, "exiting connected state");
esp_a2d_source_disconnect(connected_to_.data());
std::invoke(sEventHandler_, SimpleEvent::kConnectionStateChanged);
}
void Connected::react(const events::Disable& ev) {
@ -765,6 +766,9 @@ void Connected::react(const events::Disable& ev) {
void Connected::react(const events::PairedDeviceChanged& ev) {
transit<Idle>();
if (sPairedWith_) {
connect(*sPairedWith_);
}
}
void Connected::react(const events::SourceChanged& ev) {

@ -34,7 +34,7 @@ class Setting {
dirty_ = true;
}
}
auto get() -> std::optional<T>& { return val_; }
auto get() -> std::optional<T> { return val_; }
/* Reads the stored value from NVS and parses it into the correct type. */
auto load(nvs_handle_t) -> std::optional<T>;

@ -391,7 +391,7 @@ auto NvsStorage::BluetoothNames() -> std::vector<bluetooth::MacAndName> {
auto NvsStorage::BluetoothName(const bluetooth::mac_addr_t& mac,
std::optional<std::string> name) -> void {
std::lock_guard<std::mutex> lock{mutex_};
auto& val = bt_names_.get();
auto val = bt_names_.get();
if (!val) {
val.emplace();
}

@ -371,10 +371,10 @@ auto popRichType(lua_State* L) -> LuaValue {
}
auto Property::popValue(lua_State& s) -> bool {
LuaValue new_val;
LuaValue new_val{std::monostate{}};
if (lua_gettop(&s) >= 2) {
switch (lua_type(&s, 2)) {
case LUA_TNIL:
new_val = std::monostate{};
break;
case LUA_TNUMBER:
if (lua_isinteger(&s, 2)) {
@ -399,6 +399,7 @@ auto Property::popValue(lua_State& s) -> bool {
return false;
}
}
}
return set(new_val);
}

Loading…
Cancel
Save