Several changes:

- Fixed account renaming bug on main screen
  - Added priority to send funds UI
  - Updated lwsf external "pin"
This commit is contained in:
Lee Clagett
2025-05-27 02:31:30 -04:00
parent 42b1ae1d68
commit 4ece09bf29
4 changed files with 51 additions and 26 deletions
+1 -1
+13 -12
View File
@@ -196,8 +196,9 @@ namespace lwcli { namespace view
const std::shared_ptr<Monero::Wallet> wallet_;
ftxui::Component table_;
ftxui::Component overlay_;
ftxui::Element title_;
ftxui::Element table_cached_; //!< Does not redraw when child is enabled
const std::string title1_;
const std::string title2_;
std::unordered_map<std::size_t, std::size_t> row_map_;
const std::uint32_t account_;
@@ -209,27 +210,27 @@ namespace lwcli { namespace view
return table_;
}
ftxui::Element get_title() const
{
// UI can modify label at any time
return ftxui::text(title1_ + wallet_->getSubaddressLabel(account_, 0) + title2_);
}
public:
explicit history_(std::shared_ptr<Monero::Wallet>&& wallet, std::uint32_t account)
: ftxui::ComponentBase(),
wallet_(std::move(wallet)),
table_(),
overlay_(nullptr),
title_(nullptr),
table_cached_(nullptr),
title1_(_("Account #") + std::to_string(account) + " / "),
title2_(" / " + wallet_->address(account, 0).substr(0, 20) + "..."),
row_map_(),
account_(account)
{
if (!wallet_)
throw std::invalid_argument{"lwcli::view::history given nullptr"};
{
std::string address = _("Account #") + std::to_string(account_);
address.append(" / ").append(wallet_->getSubaddressLabel(account_, 0)).append(" / ");
address.append(wallet_->address(account_, 0).substr(0, 20)).append("...");
title_ = ftxui::text(std::move(address));
}
// perform transalation lookup once
table_ = component::table(
{_("Date"), _("Amount"), _("Payment ID"), _("Label"), _("Desription"), _("Block"), _("Fee"), _("Hash")},
@@ -341,7 +342,7 @@ namespace lwcli { namespace view
payment_id.substr(0, 16) + extended_payment_id,
std::move(label),
tx->description(),
std::to_string(tx->blockHeight()),
tx->isPending() ? "Pending" : tx->isFailed() ? "Failed" : std::to_string(tx->blockHeight()),
lwsf::displayAmount(tx->fee()),
tx->hash().substr(0, 16) + "..."
});
@@ -360,7 +361,7 @@ namespace lwcli { namespace view
{
auto table = table_->Render(); // compute balance first in callback
table_cached_ = ftxui::vbox({
title_,
get_title(),
ftxui::text(_("Balance: ") + lwsf::displayAmount(wallet_->balance(account_))),
std::move(table) | ftxui::vscroll_indicator | ftxui::yframe | ftxui::center | ftxui::flex
});
+33 -12
View File
@@ -231,18 +231,21 @@ namespace lwcli { namespace view
const std::shared_ptr<Monero::WalletManager> wm_;
const std::shared_ptr<Monero::Wallet> wal_;
const ftxui::Element title_;
const std::vector<std::string> priority_names_;
std::vector<std::shared_ptr<dest_pair>> dests_;
std::vector<buttons_tuple> dests_ui_;
unsigned animation_;
int priority_;
const ftxui::Decorator min_amount_size;
ftxui::Component overlay_;
ftxui::Component buttons_;
const ftxui::Component priority_menu_;
ftxui::Element error_;
ftxui::Component ui_;
ftxui::Element cached_;
std::future<std::tuple<std::string, std::shared_ptr<dest_pair>, bool>> oa_;
std::future<std::tuple<std::shared_ptr<Monero::PendingTransaction>, dest_group, std::string>> tx_;
const std::uint32_t account_;
unsigned animation_;
bool closing_;
bool Focusable() const override final { return true; }
@@ -253,24 +256,34 @@ namespace lwcli { namespace view
return ui_;
}
static ftxui::MenuOption toggle(const int focused)
{
auto options = ftxui::MenuOption::Toggle();
options.focused_entry = focused;
return options;
}
public:
explicit send_(std::shared_ptr<Monero::WalletManager>&& wm, std::shared_ptr<Monero::Wallet>&& wal, const std::uint32_t account)
: ftxui::ComponentBase(),
wm_(std::move(wm)),
wal_(std::move(wal)),
title_(ftxui::text(_("Send from account #") + std::to_string(account) + " (" + lwsf::displayAmount(wal_->unlockedBalance(account)) + " XMR available)")),
priority_names_({_("Auto"), _("Unimportant"), _("Normal"), _("Elevated"), _("Priority")}),
dests_(),
dests_ui_(),
animation_(0),
priority_(2),
min_amount_size(ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 5)),
overlay_(),
buttons_(),
priority_menu_(ftxui::Menu(&priority_names_, &priority_, toggle(priority_))),
error_(),
ui_(),
cached_(),
oa_(),
tx_(),
account_(account),
animation_(0),
closing_(false)
{
buttons_ = ftxui::Container::Horizontal({
@@ -312,8 +325,9 @@ namespace lwcli { namespace view
void update_ui()
{
ftxui::Components ui;
ui.reserve(dests_ui_.size() + 1);
ui.reserve(dests_ui_.size() + 2);
ui.push_back(buttons_);
ui.push_back(priority_menu_);
for (const auto& e : dests_ui_)
ui.push_back(ftxui::Container::Horizontal({std::get<0>(e), std::get<1>(e), std::get<2>(e), std::get<3>(e)}));
@@ -341,13 +355,13 @@ namespace lwcli { namespace view
for (const auto& dest : dests_)
{
const std::uint64_t amount = lwsf::amountFromString(dest->first);
if (!amount)
const std::optional<std::uint64_t> amount = lwsf::amountFromString(dest->first);
if (!amount || *amount == 0)
{
error_ = ftxui::text("Invalid amount");
return;
}
dests.second.push_back(amount);
dests.second.push_back(*amount);
if (!lwsf::addressValid(dest->second, wal_->nettype()))
{
@@ -372,7 +386,7 @@ namespace lwcli { namespace view
dests.first.push_back(dest->second);
}
const auto tx_construct = [] (std::shared_ptr<Monero::Wallet> wal, dest_group dests, const std::uint32_t account)
const auto tx_construct = [] (std::shared_ptr<Monero::Wallet> wal, dest_group dests, const std::uint32_t account, const int priority)
-> std::tuple<std::shared_ptr<Monero::PendingTransaction>, dest_group, std::string>
{
const auto dispose = [wal] (Monero::PendingTransaction* ptr)
@@ -382,7 +396,7 @@ namespace lwcli { namespace view
};
std::shared_ptr<Monero::PendingTransaction> tx{
wal->createTransactionMultDest(dests.first, {}, dests.second, 0 /*mixin_count*/, Monero::PendingTransaction::Priority_Default, account),
wal->createTransactionMultDest(dests.first, {}, dests.second, 0 /*mixin_count*/, Monero::PendingTransaction::Priority(priority), account),
dispose
};
if (!tx)
@@ -392,7 +406,7 @@ namespace lwcli { namespace view
return {nullptr, {}, tx->errorString()};
};
tx_ = std::async(std::launch::async, tx_construct, wal_, std::move(dests), account_);
tx_ = std::async(std::launch::async, tx_construct, wal_, std::move(dests), account_, priority_);
}
bool OnEvent(ftxui::Event event) override final
@@ -444,10 +458,10 @@ namespace lwcli { namespace view
error_ = ftxui::text(_("OpenAlias record is invalid for ") + std::get<1>(oa)->second);
else if (!closing_)
{
std::get<1>(oa)->second = std::move(std::get<0>(oa));
std::get<1>(oa)->second = std::move(std::get<0>(oa));
if (!std::get<2>(oa))
error_ = ftxui::text(_("dnssec verification failure for ") + std::get<1>(oa)->second);
else
else
try_construct();
}
@@ -482,7 +496,7 @@ namespace lwcli { namespace view
if (!overlay_)
{
ftxui::Elements rows;
rows.reserve(3); // dests_ui_.size() + 2);
rows.reserve(5);
if (!animate)
rows.push_back(buttons_->Render() | ftxui::hcenter);
@@ -492,6 +506,13 @@ namespace lwcli { namespace view
else
rows.push_back(ftxui::separator());
if (!animate)
{
rows.push_back(priority_menu_->Render() | ftxui::hcenter);
//rows.push_back(ftxui::hbox({ftxui::filler(), priority_menu_->Render(), ftxui::filler()}));
rows.push_back(ftxui::separator());
}
if (!closing_)
{
std::vector<std::vector<ftxui::Element>> grid;
+4 -1
View File
@@ -62,6 +62,7 @@ namespace lwcli { namespace view
{
const std::shared_ptr<Monero::Wallet> wal = state->wal;
return ftxui::Container::Horizontal({
ftxui::Button("[c]lose", [] () { throw event::close{}; }, ascii()),
ftxui::Button("[s]end", [state] () { state->overlay = send(state->wm, state->wal, state->selected_account); }, ascii()),
ftxui::Button("[a]ccounts", [state] () { state->overlay = accounts(state->wal, &state->selected_account); }, ascii()),
ftxui::Button("[r]efresh", [wal] () { wal->refreshAsync(); }, ascii()),
@@ -158,7 +159,9 @@ namespace lwcli { namespace view
return history_->OnEvent(std::move(event));
else if (!ui_->OnEvent(event))
{
if (event == ftxui::Event::s || event == ftxui::Event::S)
if (event == ftxui::Event::c || event == ftxui::Event::C)
throw event::close{};
else if (event == ftxui::Event::s || event == ftxui::Event::S)
state_.overlay = send(state_.wm, state_.wal, state_.selected_account);
else if (event == ftxui::Event::a || event == ftxui::Event::a)
state_.overlay = accounts(state_.wal, &state_.selected_account);