Added branch select
This commit is contained in:
@ -100,6 +100,7 @@ set(headers
|
||||
displays/menus/presetsmenu.h
|
||||
displays/menus/profilesmenu.h
|
||||
displays/menus/selectbatterytypemenu.h
|
||||
displays/menus/selectbuildserverbranch.h
|
||||
displays/menus/selectbuildservermenu.h
|
||||
displays/menus/selectmodemenu.h
|
||||
displays/menus/selectotabuildmenu.h
|
||||
@ -297,6 +298,7 @@ set(sources
|
||||
displays/menus/presetsmenu.cpp
|
||||
displays/menus/profilesmenu.cpp
|
||||
displays/menus/selectbatterytypemenu.cpp
|
||||
displays/menus/selectbuildserverbranch.cpp
|
||||
displays/menus/selectbuildservermenu.cpp
|
||||
displays/menus/selectmodemenu.cpp
|
||||
displays/menus/selectotabuildmenu.cpp
|
||||
|
@ -18,7 +18,111 @@
|
||||
#include "esp_http_client.h"
|
||||
|
||||
#ifdef FEATURE_OTA
|
||||
|
||||
namespace buildserver {
|
||||
|
||||
uint16_t count_available_buildserver()
|
||||
{
|
||||
uint16_t count = 0;
|
||||
for (const auto &otaServer : stringSettings.otaServers) {
|
||||
if (!otaServer.url.empty()) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
namespace SelectBranch {
|
||||
cpputils::DelayedConstruction<AsyncHttpRequest> request;
|
||||
bool request_running{false};
|
||||
bool constructedMenu{false};
|
||||
std::string request_failed{};
|
||||
std::vector<std::string> branches{};
|
||||
|
||||
void setup_request()
|
||||
{
|
||||
if (!request.constructed())
|
||||
{
|
||||
request.construct("ota-descriptor-request", espcpputils::CoreAffinity::Core0);
|
||||
}
|
||||
}
|
||||
|
||||
void start_descriptor_request(std::string server_base_url)
|
||||
{
|
||||
if (!request.constructed())
|
||||
{
|
||||
ESP_LOGW("BOBBY", "request is im oarsch");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto url = fmt::format("{}/otaDescriptor?username={}&branches", server_base_url, OTA_USERNAME);
|
||||
ESP_LOGD("BOBBY", "requesting data...");
|
||||
if (const auto result = request->start(url); !result)
|
||||
{
|
||||
ESP_LOGW("BOBBY", "request start failed");
|
||||
return;
|
||||
}
|
||||
request_running = true;
|
||||
constructedMenu = false;
|
||||
}
|
||||
|
||||
|
||||
void check_descriptor_request()
|
||||
{
|
||||
if (!request.constructed())
|
||||
{
|
||||
ESP_LOGW("BOBBY", "request is im oarsch");
|
||||
request_running = false;
|
||||
request_failed = "request is im oarsch";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request->finished())
|
||||
{
|
||||
// ESP_LOGW("BOBBY", "Request has not finished yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto helper = cpputils::makeCleanupHelper([](){ request->clearFinished(); });
|
||||
const std::string content = std::move(request->takeBuffer());
|
||||
|
||||
if (const auto result = request->result(); !result)
|
||||
{
|
||||
ESP_LOGW("BOBBY", "request failed: %.*s", result.error().size(), result.error().data());
|
||||
request_failed = result.error();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = request->result();
|
||||
ESP_LOGW("BOBBY", "Request finished: %s", content.c_str());
|
||||
parse_response(content);
|
||||
request_running = false;
|
||||
request_failed = {};
|
||||
}
|
||||
|
||||
void parse_response(std::string response)
|
||||
{
|
||||
StaticJsonDocument<1024> doc;
|
||||
|
||||
if (const auto error = deserializeJson(doc, response))
|
||||
{
|
||||
ESP_LOGE("BOBBY", "Error parsing server-response => %s (%s)", error.c_str(), response.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
branches.resize(arr.size());
|
||||
|
||||
for(JsonVariant v : arr) {
|
||||
branches.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
bool get_request_running()
|
||||
{
|
||||
return request_running;
|
||||
}
|
||||
} // namespace SelectBranch
|
||||
|
||||
namespace SelectBuild {
|
||||
void buildMenuFromJson(std::string json);
|
||||
void buildMenuRequestError(std::string error);
|
||||
|
||||
@ -27,7 +131,7 @@ namespace buildserver {
|
||||
std::array<std::string, 10> availableVersions{};
|
||||
bool request_running{false};
|
||||
std::string request_failed{};
|
||||
bool parsing_finished{true};
|
||||
bool parsing_finished{false};
|
||||
cpputils::DelayedConstruction<AsyncHttpRequest> request;
|
||||
|
||||
std::string get_ota_url_from_index(uint16_t index)
|
||||
@ -52,15 +156,6 @@ namespace buildserver {
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t count_available_buildserver()
|
||||
{
|
||||
uint16_t count = 0;
|
||||
for (const auto &otaServer : stringSettings.otaServers) {
|
||||
if (!otaServer.url.empty()) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
std::string get_hash_url(std::string hash)
|
||||
{
|
||||
return fmt::format(url_for_hashes, hash);
|
||||
@ -73,7 +168,10 @@ namespace buildserver {
|
||||
|
||||
std::string get_descriptor_url(std::string base_url)
|
||||
{
|
||||
return fmt::format("{}/otaDescriptor?username={}", base_url, OTA_USERNAME);
|
||||
if (stringSettings.otaServerBranch.empty())
|
||||
return fmt::format("{}/otaDescriptor?username={}", base_url, OTA_USERNAME);
|
||||
else
|
||||
return fmt::format("{}/otaDescriptor?username={}&branch={}", base_url, OTA_USERNAME, stringSettings.otaServerBranch);
|
||||
}
|
||||
|
||||
void parse_response_into_variables(std::string response)
|
||||
@ -172,5 +270,6 @@ namespace buildserver {
|
||||
{
|
||||
return request_running;
|
||||
}
|
||||
}
|
||||
} // namespace SelectBuild
|
||||
} // namespace buildserver
|
||||
#endif
|
||||
|
@ -8,6 +8,24 @@
|
||||
|
||||
#ifdef FEATURE_OTA
|
||||
namespace buildserver {
|
||||
|
||||
uint16_t count_available_buildserver();
|
||||
|
||||
namespace SelectBranch {
|
||||
extern cpputils::DelayedConstruction<AsyncHttpRequest> request;
|
||||
extern bool request_running;
|
||||
extern bool constructedMenu;
|
||||
void setup_request();
|
||||
void start_descriptor_request(std::string server_base_url);
|
||||
void check_descriptor_request();
|
||||
void parse_response(std::string response);
|
||||
bool get_request_running();
|
||||
extern std::string request_failed;
|
||||
extern std::vector<std::string> branches;
|
||||
} // namespace SelectBranch
|
||||
|
||||
namespace SelectBuild {
|
||||
|
||||
void buildMenuFromJson(std::string json);
|
||||
void buildMenuRequestError(std::string error);
|
||||
|
||||
@ -20,7 +38,6 @@ namespace buildserver {
|
||||
extern cpputils::DelayedConstruction<AsyncHttpRequest> request;
|
||||
|
||||
std::string get_ota_url_from_index(uint16_t index);
|
||||
uint16_t count_available_buildserver();
|
||||
std::string get_hash_url(std::string hash);
|
||||
std::string get_latest_url();
|
||||
std::string get_descriptor_url(std::string base_url);
|
||||
@ -29,5 +46,6 @@ namespace buildserver {
|
||||
void start_descriptor_request(std::string server_base_url);
|
||||
void check_descriptor_request();
|
||||
bool get_request_running();
|
||||
}
|
||||
} // namespace SelectBuild
|
||||
} // namespace buildserver
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "icons/presets.h"
|
||||
#include "icons/update.h"
|
||||
#include "displays/menus/selectotabuildmenu.h"
|
||||
#include "displays/menus/selectbuildserverbranch.h"
|
||||
#include "displays/menus/selectbuildservermenu.h"
|
||||
#include "displays/menus/mainmenu.h"
|
||||
#include "displays/updatedisplay.h"
|
||||
@ -21,6 +22,7 @@ using namespace espgui;
|
||||
OtaMenu::OtaMenu()
|
||||
{
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILD>, SwitchScreenAction<SelectBuildMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_BRANCH>, SwitchScreenAction<SelectBuildserverBranchMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATENOW>, SwitchScreenAction<UpdateDisplay>, StaticMenuItemIcon<&bobbyicons::update>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
|
128
main/displays/menus/selectbuildserverbranch.cpp
Normal file
128
main/displays/menus/selectbuildserverbranch.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#ifdef FEATURE_OTA
|
||||
#include "selectbuildserverbranch.h"
|
||||
|
||||
// 3rd party includes
|
||||
#include <espwifistack.h>
|
||||
|
||||
// local includes
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "buildserver.h"
|
||||
#include "displays/menus/otamenu.h"
|
||||
#include "globals.h"
|
||||
#include "icons/back.h"
|
||||
#include "icons/reboot.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define ERR_MESSAGE(text) \
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<text>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>(); \
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>(); \
|
||||
return;
|
||||
|
||||
using namespace espgui;
|
||||
using namespace buildserver;
|
||||
using namespace SelectBuildServerBranch;
|
||||
|
||||
namespace SelectBuildServerBranch {
|
||||
std::string CurrentBranch::text() const
|
||||
{
|
||||
return stringSettings.otaServerBranch.empty() ? "All builds" : stringSettings.otaServerBranch;
|
||||
}
|
||||
|
||||
std::string BranchMenuItem::text() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void BranchMenuItem::setName(std::string &&name)
|
||||
{
|
||||
m_name = std::move(name);
|
||||
}
|
||||
|
||||
void BranchMenuItem::setName(const std::string &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void BranchMenuItem::triggered()
|
||||
{
|
||||
stringSettings.otaServerBranch = m_name;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void ClearBranchAction::triggered()
|
||||
{
|
||||
stringSettings.otaServerBranch = {};
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
SelectBuildserverBranchMenu::SelectBuildserverBranchMenu()
|
||||
{
|
||||
using namespace SelectBuildServerBranch;
|
||||
|
||||
if (count_available_buildserver() < 1)
|
||||
{
|
||||
ERR_MESSAGE(TEXT_OTA_NOBUILDSERVERAVAILABLE); // E:No server saved.
|
||||
}
|
||||
|
||||
if (stringSettings.otaServerUrl.empty())
|
||||
{
|
||||
ERR_MESSAGE(TEXT_OTA_NOBUILDSERVERSELECTED); // E:No server selected.
|
||||
}
|
||||
|
||||
if (const auto staStatus = wifi_stack::get_sta_status(); staStatus != wifi_stack::WiFiStaStatus::CONNECTED)
|
||||
{
|
||||
ERR_MESSAGE(TEXT_OTA_NOCONNECTION); // E:No internet.
|
||||
}
|
||||
|
||||
SelectBranch::setup_request();
|
||||
SelectBranch::start_descriptor_request(stringSettings.otaServerUrl);
|
||||
}
|
||||
|
||||
void SelectBuildserverBranchMenu::update()
|
||||
{
|
||||
using namespace SelectBranch;
|
||||
if(get_request_running())
|
||||
{
|
||||
check_descriptor_request();
|
||||
if (!request_failed.empty())
|
||||
{
|
||||
this->buildMenuRequestError(request_failed);
|
||||
request_failed = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (!constructedMenu && branches.size() > 0)
|
||||
{
|
||||
constructedMenu = true;
|
||||
constructMenuItem<makeComponent<MenuItem, CurrentBranch, DisabledColor, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
|
||||
|
||||
for (const std::string &branch : branches)
|
||||
{
|
||||
if (branch.empty())
|
||||
continue;
|
||||
auto &menuitem = constructMenuItem<BranchMenuItem>();
|
||||
menuitem.setName(branch);
|
||||
}
|
||||
|
||||
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_BRANCH_CLEAR>, ClearBranchAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
}
|
||||
Base::update();
|
||||
}
|
||||
|
||||
void SelectBuildserverBranchMenu::back()
|
||||
{
|
||||
switchScreen<OtaMenu>();
|
||||
}
|
||||
|
||||
void SelectBuildserverBranchMenu::buildMenuRequestError(std::string error)
|
||||
{
|
||||
auto &item = constructMenuItem<makeComponent<MenuItem, ChangeableText, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
|
||||
item.setTitle(error);
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
}
|
||||
#endif
|
46
main/displays/menus/selectbuildserverbranch.h
Normal file
46
main/displays/menus/selectbuildserverbranch.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
// 3rd party includes
|
||||
#include <menudisplay.h>
|
||||
#include <texts.h>
|
||||
#ifdef FEATURE_OTA
|
||||
|
||||
namespace SelectBuildServerBranch {
|
||||
class CurrentBranch : public virtual espgui::TextInterface
|
||||
{
|
||||
public:
|
||||
std::string text() const override;
|
||||
};
|
||||
|
||||
class BranchMenuItem : public espgui::MenuItem
|
||||
{
|
||||
public:
|
||||
std::string text() const override;
|
||||
void setName(std::string &&name);
|
||||
void setName(const std::string &name);
|
||||
|
||||
void triggered() override;
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
class ClearBranchAction : public virtual espgui::ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override;
|
||||
};
|
||||
}
|
||||
|
||||
class SelectBuildserverBranchMenu :
|
||||
public espgui::MenuDisplay,
|
||||
public espgui::StaticText<TEXT_SELECT_BRANCH>
|
||||
{
|
||||
using Base = espgui::MenuDisplay;
|
||||
public:
|
||||
SelectBuildserverBranchMenu();
|
||||
void buildMenuRequestError(std::string error);
|
||||
void update() override;
|
||||
void back() override;
|
||||
};
|
||||
|
||||
#endif
|
@ -51,6 +51,7 @@ StringSettings makeDefaultStringSettings()
|
||||
.otaServerUrl = {},
|
||||
#endif
|
||||
.ap_password = STRING(AP_PASSWORD),
|
||||
.otaServerBranch = {}
|
||||
};
|
||||
}
|
||||
} // namespace presets
|
||||
|
@ -49,6 +49,7 @@ struct StringSettings
|
||||
std::string dns_key;
|
||||
#endif
|
||||
std::string ap_password;
|
||||
std::string otaServerBranch;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -118,6 +119,7 @@ void StringSettings::executeForEveryCommonSetting(T &&callable)
|
||||
callable("dnskey", dns_key);
|
||||
#endif
|
||||
callable("ap_pw", ap_password);
|
||||
callable("otaBranch", otaServerBranch);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -533,4 +533,8 @@ char TEXT_STATSCLEAR[] = "Clear current km";
|
||||
char TEXT_POWERSUPPLY[] = "Powersupply";
|
||||
#endif
|
||||
char TEXT_REENABLE_MENUITEMS[] = "Show advanced";
|
||||
|
||||
//SelectBuildserverBranchMenu
|
||||
char TEXT_SELECT_BRANCH[] = "Select Branch";
|
||||
char TEXT_SELECT_BRANCH_CLEAR[] = "Clear Branch";
|
||||
} // namespace
|
||||
|
@ -532,6 +532,10 @@ extern char TEXT_STATSCLEAR[];
|
||||
extern char TEXT_POWERSUPPLY[];
|
||||
#endif
|
||||
extern char TEXT_REENABLE_MENUITEMS[];
|
||||
|
||||
//SelectBuildserverBranchMenu
|
||||
extern char TEXT_SELECT_BRANCH[];
|
||||
extern char TEXT_SELECT_BRANCH_CLEAR[];
|
||||
} // namespace
|
||||
|
||||
using namespace bobbytexts;
|
||||
|
Reference in New Issue
Block a user