mirror of
https://github.com/wownero/lwcli-wow.git
synced 2026-10-17 06:51:25 +02:00
Merge remote-tracking branch 'upstream/main'
# Conflicts: # external/lwsf
This commit is contained in:
Vendored
+1
-1
Submodule external/lwsf updated: bd58c505e0...db85219a97
@@ -26,6 +26,7 @@
|
|||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <ftxui/component/component.hpp>
|
#include <ftxui/component/component.hpp>
|
||||||
#include <ftxui/component/event.hpp>
|
#include <ftxui/component/event.hpp>
|
||||||
@@ -196,8 +197,6 @@ namespace lwcli { namespace component
|
|||||||
row.Decorate(ftxui::focus);
|
row.Decorate(ftxui::focus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
selected_ = -1;
|
|
||||||
|
|
||||||
if (selected_ != highlighted_ && min_row() <= highlighted_ && highlighted_ < rows_)
|
if (selected_ != highlighted_ && min_row() <= highlighted_ && highlighted_ < rows_)
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,7 @@
|
|||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -289,7 +290,8 @@ int main(int, const char* argv[])
|
|||||||
|
|
||||||
auto window = ftxui::CatchEvent(lwcli::view::manager(std::move(wm), std::move(prog.file)), [&] (ftxui::Event event)
|
auto window = ftxui::CatchEvent(lwcli::view::manager(std::move(wm), std::move(prog.file)), [&] (ftxui::Event event)
|
||||||
{
|
{
|
||||||
state.last_event = std::chrono::steady_clock::now().time_since_epoch().count();
|
if (event != lwcli::event::refresh_wallet)
|
||||||
|
state.last_event = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||||
if (event == ftxui::Event::CtrlC)
|
if (event == ftxui::Event::CtrlC)
|
||||||
{
|
{
|
||||||
state.screen.ExitLoopClosure()();
|
state.screen.ExitLoopClosure()();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <ftxui/component/component.hpp>
|
#include <ftxui/component/component.hpp>
|
||||||
#include <ftxui/component/event.hpp>
|
#include <ftxui/component/event.hpp>
|
||||||
#include <ftxui/dom/table.hpp>
|
#include <ftxui/dom/table.hpp>
|
||||||
|
|||||||
+133
-116
@@ -26,6 +26,7 @@
|
|||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <ftxui/component/component.hpp>
|
#include <ftxui/component/component.hpp>
|
||||||
#include <ftxui/component/event.hpp>
|
#include <ftxui/component/event.hpp>
|
||||||
@@ -60,37 +61,72 @@ namespace lwcli { namespace view
|
|||||||
Monero::TransactionHistory* const history_;
|
Monero::TransactionHistory* const history_;
|
||||||
Monero::TransactionInfo const* info_;
|
Monero::TransactionInfo const* info_;
|
||||||
std::string note_;
|
std::string note_;
|
||||||
|
std::string hash_;
|
||||||
|
std::vector<Monero::TransactionInfo::Transfer> transfers_;
|
||||||
ftxui::Component note_input_;
|
ftxui::Component note_input_;
|
||||||
const ftxui::Component cancel_;
|
ftxui::Component buttons_;
|
||||||
ftxui::Component ok_;
|
|
||||||
ftxui::Component container_;
|
ftxui::Component container_;
|
||||||
ftxui::Element title_;
|
|
||||||
ftxui::Elements timestamp_;
|
bool Focusable() const override final { return true; }
|
||||||
ftxui::Elements payment_id_;
|
ftxui::Component ActiveChild() override final { return container_; }
|
||||||
ftxui::Elements amount_;
|
|
||||||
ftxui::Elements fee_;
|
|
||||||
ftxui::Elements minors_;
|
|
||||||
ftxui::Elements coinbase_;
|
|
||||||
|
|
||||||
bool OnEvent(ftxui::Event event) override final
|
bool OnEvent(ftxui::Event event) override final
|
||||||
{
|
{
|
||||||
if (event == ftxui::Event::CtrlQ)
|
if (event == event::refresh_wallet)
|
||||||
|
return on_refresh(history_->transaction(hash_));
|
||||||
|
else if (event == ftxui::Event::CtrlQ)
|
||||||
throw event::close{};
|
throw event::close{};
|
||||||
return container_->OnEvent(std::move(event));
|
return container_->OnEvent(std::move(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ftxui::Element OnRender() override final
|
virtual ftxui::Element OnRender() override final
|
||||||
{
|
{
|
||||||
|
auto buttons = ftxui::hcenter(buttons_->Render());
|
||||||
|
if (!info_)
|
||||||
|
{
|
||||||
|
return ftxui::window(
|
||||||
|
ftxui::text(_("Tx ") + hash_),
|
||||||
|
ftxui::vbox(std::move(buttons), ftxui::separator(), ftxui::text("No longer available"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Elements minors;
|
||||||
|
{
|
||||||
|
std::string minors_text;
|
||||||
|
for (const std::uint32_t minor : info_->subaddrIndex())
|
||||||
|
{
|
||||||
|
if (!minors.empty())
|
||||||
|
minors_text.append(", ");
|
||||||
|
minors_text.append(std::to_string(minor));
|
||||||
|
}
|
||||||
|
minors = {ftxui::text(_("Subaddress Minor: ")), ftxui::text(std::move(minors_text))};
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Elements timestamp;
|
||||||
|
{
|
||||||
|
std::tm expanded{};
|
||||||
|
const std::time_t raw = info_->timestamp();
|
||||||
|
if (gmtime_r(std::addressof(raw), std::addressof(expanded)))
|
||||||
|
{
|
||||||
|
char buf[100] = {0};
|
||||||
|
if (sizeof(buf) <= std::strftime(buf, sizeof(buf), "%B %d %Y %I:%M:%S UTC", std::addressof(expanded)))
|
||||||
|
throw std::runtime_error{"strftime failed"};
|
||||||
|
timestamp = {ftxui::text(_("Timestamp: ")), ftxui::text(buf)};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
timestamp = {ftxui::text(_("Timestamp: ")), ftxui::text("gmtime failure")};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ftxui::Elements> grid{
|
std::vector<ftxui::Elements> grid{
|
||||||
{ftxui::text(_("Description: ")), note_input_->Render()},
|
{ftxui::text(_("Description: ")), note_input_->Render()},
|
||||||
timestamp_,
|
std::move(timestamp),
|
||||||
payment_id_,
|
{ftxui::text(_("Payment ID: ")), ftxui::text(info_->paymentId())},
|
||||||
{ftxui::text(_("Confirmations: ")), ftxui::text(std::to_string(info_->confirmations()))},
|
{ftxui::text(_("Confirmations: ")), ftxui::text(std::to_string(info_->confirmations()))},
|
||||||
amount_,
|
{ftxui::text(_("Amount: ")), ftxui::text(print_amount(*info_))},
|
||||||
fee_,
|
{ftxui::text(_("Fee: ")), ftxui::text(lwsf::displayAmount(info_->fee()))},
|
||||||
{ftxui::text(_("Block Height: ")), ftxui::text(std::to_string(info_->blockHeight()))},
|
{ftxui::text(_("Block Height: ")), ftxui::text(std::to_string(info_->blockHeight()))},
|
||||||
minors_,
|
std::move(minors),
|
||||||
coinbase_
|
{ftxui::text(_("Coinbase: ")), ftxui::text(info_->isCoinbase() ? _("Yes"): _("No"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::size_t base_size = grid.size();
|
const std::size_t base_size = grid.size();
|
||||||
@@ -110,7 +146,7 @@ namespace lwcli { namespace view
|
|||||||
ftxui::Elements vertical;
|
ftxui::Elements vertical;
|
||||||
vertical.reserve(4);
|
vertical.reserve(4);
|
||||||
|
|
||||||
vertical.push_back(ftxui::hcenter(ftxui::hbox(cancel_->Render(), ok_->Render())));
|
vertical.push_back(std::move(buttons));
|
||||||
if (info_->isFailed())
|
if (info_->isFailed())
|
||||||
vertical.push_back(ftxui::inverted(ftxui::hcenter(ftxui::text(_("FAILED")))));
|
vertical.push_back(ftxui::inverted(ftxui::hcenter(ftxui::text(_("FAILED")))));
|
||||||
else if (info_->isPending())
|
else if (info_->isPending())
|
||||||
@@ -120,74 +156,48 @@ namespace lwcli { namespace view
|
|||||||
|
|
||||||
vertical.push_back(ftxui::gridbox(std::move(grid)));
|
vertical.push_back(ftxui::gridbox(std::move(grid)));
|
||||||
|
|
||||||
return ftxui::window(title_, ftxui::vbox(std::move(vertical)));
|
return ftxui::window(ftxui::text(_("Tx ") + hash_), ftxui::vbox(std::move(vertical)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool on_refresh(const Monero::TransactionInfo* info)
|
||||||
|
{
|
||||||
|
info_ = info;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit tx_details(Monero::TransactionHistory* history, std::size_t index)
|
explicit tx_details(Monero::TransactionHistory* history, const Monero::TransactionInfo* info)
|
||||||
: history_(history),
|
: history_(history),
|
||||||
info_(nullptr),
|
info_(nullptr),
|
||||||
note_(),
|
note_(),
|
||||||
|
hash_(),
|
||||||
|
transfers_(),
|
||||||
note_input_(nullptr),
|
note_input_(nullptr),
|
||||||
cancel_(ftxui::Button(_("Cancel"), [] () { throw event::close{}; }, ftxui::ButtonOption::Ascii())),
|
buttons_(),
|
||||||
ok_(nullptr),
|
container_()
|
||||||
container_(),
|
|
||||||
title_(nullptr),
|
|
||||||
timestamp_(),
|
|
||||||
payment_id_(),
|
|
||||||
amount_(),
|
|
||||||
fee_(),
|
|
||||||
minors_(),
|
|
||||||
coinbase_()
|
|
||||||
{
|
{
|
||||||
if (!history_)
|
if (!history_)
|
||||||
throw std::runtime_error{"unexpected nullptr"};
|
throw std::runtime_error{"unexpected nullptr"};
|
||||||
|
|
||||||
info_ = history->transaction(index);
|
on_refresh(info);
|
||||||
if (!info_)
|
hash_ = info->hash();
|
||||||
throw std::runtime_error{"unexpected nullptr"};
|
|
||||||
|
|
||||||
title_ = ftxui::text(_("Tx ") + info_->hash());
|
|
||||||
{
|
|
||||||
std::tm expanded{};
|
|
||||||
const std::time_t timestamp = info_->timestamp();
|
|
||||||
if (!gmtime_r(std::addressof(timestamp), std::addressof(expanded)))
|
|
||||||
throw std::runtime_error{"gmtime failure"};
|
|
||||||
|
|
||||||
char buf[100] = {0};
|
note_ = info->description();
|
||||||
if (sizeof(buf) <= std::strftime(buf, sizeof(buf), "%B %d %Y %I:%M:%S UTC", std::addressof(expanded)))
|
|
||||||
throw std::runtime_error{"strftime failed"};
|
|
||||||
timestamp_ = {ftxui::text(_("Timestamp: ")), ftxui::text(buf)};
|
|
||||||
}
|
|
||||||
payment_id_ = {ftxui::text(_("Payment ID: ")), ftxui::text(info_->paymentId())};
|
|
||||||
amount_ = {ftxui::text(_("Amount: ")), ftxui::text(print_amount(*info_))};
|
|
||||||
fee_ = {ftxui::text(_("Fee: ")), ftxui::text(lwsf::displayAmount(info_->fee()))};
|
|
||||||
{
|
|
||||||
std::string minors;
|
|
||||||
for (const std::uint32_t minor : info_->subaddrIndex())
|
|
||||||
{
|
|
||||||
if (!minors.empty())
|
|
||||||
minors.append(", ");
|
|
||||||
minors.append(std::to_string(minor));
|
|
||||||
}
|
|
||||||
minors_ = {ftxui::text(_("Subaddress Minor: ")), ftxui::text(std::move(minors))};
|
|
||||||
}
|
|
||||||
coinbase_ = {ftxui::text(_("Coinbase: ")), ftxui::text(info_->isCoinbase() ? _("Yes"): _("No"))};
|
|
||||||
|
|
||||||
note_ = info_->description();
|
|
||||||
auto options = ftxui::InputOption::Default();
|
auto options = ftxui::InputOption::Default();
|
||||||
options.cursor_position = note_.size();
|
options.cursor_position = note_.size();
|
||||||
|
options.multiline = false;
|
||||||
note_input_ = ftxui::Input(¬e_, std::move(options));
|
note_input_ = ftxui::Input(¬e_, std::move(options));
|
||||||
|
|
||||||
ok_ = ftxui::Button(_("OK"), [this] () {
|
buttons_ = ftxui::Container::Horizontal({
|
||||||
history_->setTxNote(info_->hash(), note_);
|
ftxui::Button(_("Cancel"), [] () { throw event::close{}; }, ftxui::ButtonOption::Ascii()),
|
||||||
throw event::close{};
|
ftxui::Button(_("OK"), [this] () {
|
||||||
}, ftxui::ButtonOption::Ascii());
|
history_->setTxNote(hash_, note_);
|
||||||
|
throw event::close{};
|
||||||
container_ = ftxui::Container::Vertical({
|
}, ftxui::ButtonOption::Ascii())
|
||||||
ftxui::Container::Horizontal({cancel_, ok_}),
|
|
||||||
note_input_
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
container_ = ftxui::Container::Vertical({buttons_, note_input_});
|
||||||
|
Add(container_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,10 +206,9 @@ namespace lwcli { namespace view
|
|||||||
const std::shared_ptr<Monero::Wallet> wallet_;
|
const std::shared_ptr<Monero::Wallet> wallet_;
|
||||||
ftxui::Component table_;
|
ftxui::Component table_;
|
||||||
ftxui::Component overlay_;
|
ftxui::Component overlay_;
|
||||||
ftxui::Element table_cached_; //!< Does not redraw when child is enabled
|
|
||||||
const std::string title1_;
|
const std::string title1_;
|
||||||
const std::string title2_;
|
const std::string title2_;
|
||||||
std::unordered_map<std::size_t, std::size_t> row_map_;
|
std::vector<const Monero::TransactionInfo*> row_map_;
|
||||||
const std::uint32_t account_;
|
const std::uint32_t account_;
|
||||||
|
|
||||||
bool Focusable() const override final { return true; }
|
bool Focusable() const override final { return true; }
|
||||||
@@ -216,13 +225,36 @@ namespace lwcli { namespace view
|
|||||||
return ftxui::text(title1_ + wallet_->getSubaddressLabel(account_, 0) + title2_);
|
return ftxui::text(title1_ + wallet_->getSubaddressLabel(account_, 0) + title2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_history()
|
||||||
|
{
|
||||||
|
Monero::TransactionHistory* tx_history = wallet_->history();
|
||||||
|
if (!tx_history)
|
||||||
|
throw std::runtime_error{"unexpeted history nullptr"};
|
||||||
|
tx_history->refresh();
|
||||||
|
|
||||||
|
std::map<std::pair<std::uint64_t, std::string>, const Monero::TransactionInfo*, std::greater<>> ordered;
|
||||||
|
const auto history = tx_history->getAll();
|
||||||
|
for (const Monero::TransactionInfo* tx : history)
|
||||||
|
{
|
||||||
|
if (!tx)
|
||||||
|
throw std::runtime_error{"unexpected tx_info nullptr"};
|
||||||
|
|
||||||
|
if (tx->subaddrAccount() == account_)
|
||||||
|
ordered.try_emplace({tx->blockHeight(), tx->hash()}, tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
row_map_.clear();
|
||||||
|
row_map_.reserve(ordered.size());
|
||||||
|
for (const auto& entry : ordered)
|
||||||
|
row_map_.push_back(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit history_(std::shared_ptr<Monero::Wallet>&& wallet, std::uint32_t account)
|
explicit history_(std::shared_ptr<Monero::Wallet>&& wallet, std::uint32_t account)
|
||||||
: ftxui::ComponentBase(),
|
: ftxui::ComponentBase(),
|
||||||
wallet_(std::move(wallet)),
|
wallet_(std::move(wallet)),
|
||||||
table_(),
|
table_(),
|
||||||
overlay_(nullptr),
|
overlay_(nullptr),
|
||||||
table_cached_(nullptr),
|
|
||||||
title1_(_("Account #") + std::to_string(account) + " / "),
|
title1_(_("Account #") + std::to_string(account) + " / "),
|
||||||
title2_(" / " + wallet_->address(account, 0).substr(0, 20) + "..."),
|
title2_(" / " + wallet_->address(account, 0).substr(0, 20) + "..."),
|
||||||
row_map_(),
|
row_map_(),
|
||||||
@@ -231,6 +263,8 @@ namespace lwcli { namespace view
|
|||||||
if (!wallet_)
|
if (!wallet_)
|
||||||
throw std::invalid_argument{"lwcli::view::history given nullptr"};
|
throw std::invalid_argument{"lwcli::view::history given nullptr"};
|
||||||
|
|
||||||
|
load_history();
|
||||||
|
|
||||||
// perform transalation lookup once
|
// perform transalation lookup once
|
||||||
table_ = component::table(
|
table_ = component::table(
|
||||||
{_("Date"), _("Amount"), _("Payment ID"), _("Label"), _("Desription"), _("Block"), _("Fee"), _("Hash")},
|
{_("Date"), _("Amount"), _("Payment ID"), _("Label"), _("Desription"), _("Block"), _("Fee"), _("Hash")},
|
||||||
@@ -256,7 +290,14 @@ namespace lwcli { namespace view
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (overlay_)
|
if (event == event::refresh_wallet)
|
||||||
|
{
|
||||||
|
load_history();
|
||||||
|
if (overlay_)
|
||||||
|
overlay_->OnEvent(std::move(event));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (overlay_)
|
||||||
{
|
{
|
||||||
overlay_->OnEvent(std::move(event));
|
overlay_->OnEvent(std::move(event));
|
||||||
return true;
|
return true;
|
||||||
@@ -280,45 +321,28 @@ namespace lwcli { namespace view
|
|||||||
|
|
||||||
std::vector<std::vector<std::string>> transaction_list()
|
std::vector<std::vector<std::string>> transaction_list()
|
||||||
{
|
{
|
||||||
Monero::TransactionHistory* tx_history = wallet_->history();
|
|
||||||
if (!tx_history)
|
|
||||||
throw std::runtime_error{"unexpected history nullptr"};
|
|
||||||
|
|
||||||
std::map<std::pair<std::uint64_t, std::string>, std::pair<const Monero::TransactionInfo*, std::size_t>, std::greater<>> ordered;
|
|
||||||
tx_history->refresh();
|
|
||||||
const auto history = tx_history->getAll();
|
|
||||||
for (std::size_t i = 0; i < history.size(); ++i)
|
|
||||||
{
|
|
||||||
const Monero::TransactionInfo* tx = history[i];
|
|
||||||
if (!tx)
|
|
||||||
throw std::runtime_error{"unexpected tx_info nullptr"};
|
|
||||||
|
|
||||||
if (tx->subaddrAccount() == account_)
|
|
||||||
ordered.try_emplace({tx->blockHeight(), tx->hash()}, tx, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::vector<std::string>> rows;
|
std::vector<std::vector<std::string>> rows;
|
||||||
rows.reserve(ordered.size() + 2);
|
rows.reserve(row_map_.size() + 2);
|
||||||
|
|
||||||
std::size_t i = 0;
|
for (const Monero::TransactionInfo* tx : row_map_)
|
||||||
row_map_.clear();
|
|
||||||
for (const auto& entry : ordered)
|
|
||||||
{
|
{
|
||||||
const Monero::TransactionInfo* tx = entry.second.first;
|
|
||||||
row_map_.emplace(i, entry.second.second);
|
|
||||||
|
|
||||||
const std::uint64_t amount = tx->amount();
|
const std::uint64_t amount = tx->amount();
|
||||||
const int direction = tx->direction();
|
const int direction = tx->direction();
|
||||||
const std::uint64_t fee = tx->fee();
|
const std::uint64_t fee = tx->fee();
|
||||||
|
|
||||||
|
char date[12] = {0};
|
||||||
std::tm expanded{};
|
std::tm expanded{};
|
||||||
const std::time_t timestamp = tx->timestamp();
|
const std::time_t timestamp = tx->timestamp();
|
||||||
if (!gmtime_r(std::addressof(timestamp), std::addressof(expanded)))
|
if (gmtime_r(std::addressof(timestamp), std::addressof(expanded)))
|
||||||
throw std::runtime_error{"gmtime failure"};
|
{
|
||||||
|
if (sizeof(date) - 1 != std::strftime(date, sizeof(date), "%Y/%m/%d ", std::addressof(expanded)))
|
||||||
char date[12] = {0};
|
throw std::runtime_error{"strftime failed"};
|
||||||
if (sizeof(date) - 1 != std::strftime(date, sizeof(date), "%Y/%m/%d ", std::addressof(expanded)))
|
}
|
||||||
throw std::runtime_error{"strftime failed"};
|
else
|
||||||
|
{
|
||||||
|
std::strncpy(date, "gmtime fail", sizeof(date));
|
||||||
|
date[sizeof(date) - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string payment_id = tx->paymentId();
|
std::string payment_id = tx->paymentId();
|
||||||
if (payment_id.size() == 16 && payment_id.find_first_not_of('0') == std::string::npos)
|
if (payment_id.size() == 16 && payment_id.find_first_not_of('0') == std::string::npos)
|
||||||
@@ -346,8 +370,6 @@ namespace lwcli { namespace view
|
|||||||
lwsf::displayAmount(tx->fee()),
|
lwsf::displayAmount(tx->fee()),
|
||||||
tx->hash().substr(0, 16) + "..."
|
tx->hash().substr(0, 16) + "..."
|
||||||
});
|
});
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
@@ -355,19 +377,14 @@ namespace lwcli { namespace view
|
|||||||
|
|
||||||
ftxui::Element OnRender() override final
|
ftxui::Element OnRender() override final
|
||||||
{
|
{
|
||||||
/* Do not redraw table when showing tx. the
|
auto table = ftxui::vbox({
|
||||||
history()->refresh() call can invalidate pointers */
|
get_title(),
|
||||||
|
ftxui::text(_("Balance: ") + lwsf::displayAmount(wallet_->balance(account_))),
|
||||||
|
table_->Render() | ftxui::vscroll_indicator | ftxui::yframe | ftxui::center | ftxui::flex
|
||||||
|
});
|
||||||
if (!overlay_)
|
if (!overlay_)
|
||||||
{
|
return table;
|
||||||
auto table = table_->Render(); // compute balance first in callback
|
return ftxui::dbox(std::move(table), decorate::overlay(overlay_->Render()));
|
||||||
table_cached_ = ftxui::vbox({
|
|
||||||
get_title(),
|
|
||||||
ftxui::text(_("Balance: ") + lwsf::displayAmount(wallet_->balance(account_))),
|
|
||||||
std::move(table) | ftxui::vscroll_indicator | ftxui::yframe | ftxui::center | ftxui::flex
|
|
||||||
});
|
|
||||||
return table_cached_;
|
|
||||||
}
|
|
||||||
return ftxui::dbox(table_cached_, decorate::overlay(overlay_->Render()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // anonymous
|
} // anonymous
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace lwcli { namespace view
|
|||||||
ftxui::Component ActiveChild() override final
|
ftxui::Component ActiveChild() override final
|
||||||
{
|
{
|
||||||
if (state_.overlay)
|
if (state_.overlay)
|
||||||
return state_.overlay;
|
return state_.overlay;
|
||||||
return ui_;
|
return ui_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ namespace lwcli { namespace view
|
|||||||
const bool has_overlay = bool(state_.overlay);
|
const bool has_overlay = bool(state_.overlay);
|
||||||
|
|
||||||
if (event == event::refresh_wallet)
|
if (event == event::refresh_wallet)
|
||||||
return true;
|
return history_->OnEvent(std::move(event));
|
||||||
else if (state_.overlay)
|
else if (state_.overlay)
|
||||||
state_.overlay->OnEvent(std::move(event));
|
state_.overlay->OnEvent(std::move(event));
|
||||||
else if (event == ftxui::Event::CtrlQ)
|
else if (event == ftxui::Event::CtrlQ)
|
||||||
|
|||||||
Reference in New Issue
Block a user