Files
MuditaOS/module-apps/application-messages/widgets/SMSInputWidget.cpp
Lefucjusz 5a37d3bdbc [MOS-27] Fix invisible message text after pasting
Fix of the issue that pasting previously copied
text in new message field on thread screen
resulted in text shown in gray and invisibility
of each subsequently entered character.

Further analysis of this issue shown two
additional bugs in this place in code,
as a result a decision to completely
remove 'Reply' prompt text has been
made. Extended description of these
issues can be found in comment under
MOS-27 Jira ticket.
2023-01-04 16:45:40 +01:00

165 lines
6.6 KiB
C++

// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ApplicationMessages.hpp"
#include "MessagesStyle.hpp"
#include <AppWindow.hpp>
#include <Font.hpp>
#include <i18n/i18n.hpp>
#include <service-cellular/service-cellular/MessageConstants.hpp>
#include <SMSInputWidget.hpp>
#include <Style.hpp>
#include <parsers/TextParse.hpp>
#include <algorithm>
#include <utility>
namespace gui
{
SMSInputWidget::SMSInputWidget(app::ApplicationCommon *application) : application(application)
{
setMinimumSize(style::window::default_body_width, style::messages::smsInput::min_h);
setMargins(Margins(
style::messages::smsInput::new_sms_left_margin, style::messages::smsInput::new_sms_vertical_spacer, 0, 0));
setEdges(gui::RectangleEdge::None);
body = new HBox(this, 0, 0, 0, 0);
body->setEdges(RectangleEdge::Bottom);
body->setMaximumSize(style::window::default_body_width, style::messages::smsInput::max_input_h);
deleteByList = false;
inputText = new gui::Text(body, 0, 0, 0, 0, ExpandMode::Up);
inputText->setMaximumSize(style::messages::smsInput::default_input_w, style::messages::smsInput::max_input_h);
inputText->setMinimumSize(style::messages::smsInput::default_input_w,
style::messages::smsInput::default_input_h);
inputText->setTextLimitType(gui::TextLimitType::MaxSignsCount, msgConstants::maxConcatenatedLen);
inputText->setFont(style::window::font::medium);
inputText->setPadding(Padding(0, 0, 0, style::messages::smsInput::bottom_padding));
inputText->setPenFocusWidth(style::window::default_border_focus_w);
inputText->setPenWidth(style::window::default_border_focus_w);
inputText->setEdges(gui::RectangleEdge::None);
replyImage = new Image(body, 0, 0, "messages_reply_32px_W_M");
replyImage->setAlignment(Alignment(gui::Alignment::Vertical::Bottom));
replyImage->setMargins(Margins(0, 0, 0, style::messages::smsInput::reply_bottom_margin));
replyImage->activeItem = false;
inputCallback = [&]([[maybe_unused]] Item &item, const InputEvent &event) { return inputText->onInput(event); };
focusChangedCallback = [this]([[maybe_unused]] Item &item) {
setFocusItem(focus ? body : nullptr);
return true;
};
inputText->setInputMode(new InputMode(
{InputMode::Abc, InputMode::ABC, InputMode::abc, InputMode::digit},
[=](const UTF8 &Text) { application->getCurrentWindow()->navBarTemporaryMode(Text); },
[=]() { application->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[=]() { application->getCurrentWindow()->selectSpecialCharacter(); }));
inputText->inputCallback = [this, application]([[maybe_unused]] Item &, const InputEvent &event) {
if (event.isShortRelease(KeyCode::KEY_LF)) {
auto app = dynamic_cast<app::ApplicationMessages *>(application);
assert(app != nullptr);
return app->newMessageOptions(application->getCurrentWindow()->getName(), inputText);
}
return false;
};
inputText->focusChangedCallback = [this, application]([[maybe_unused]] Item &) -> bool {
assert(body != nullptr);
assert(application != nullptr);
const auto threadViewWindow = application->getWindow(gui::name::window::thread_view);
if (inputText->focus) {
inputText->setCursorStartPosition(CursorStartPosition::DocumentEnd);
threadViewWindow->setNavBarText(utils::translate(utils::translate(style::strings::common::send)),
nav_bar::Side::Center);
}
else {
threadViewWindow->setNavBarText(utils::translate(style::strings::common::reply), nav_bar::Side::Center);
}
return true;
};
dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
if (newDim.w == style::listview::item_width_with_scroll - style::messages::smsInput::new_sms_left_margin) {
inputText->setMinimumWidth(style::messages::smsInput::default_input_w);
inputText->setMaximumWidth(style::messages::smsInput::default_input_w);
}
else {
inputText->setMinimumWidth(style::messages::smsInput::default_input_w +
style::listview::scroll::item_margin);
inputText->setMaximumWidth(style::messages::smsInput::default_input_w +
style::listview::scroll::item_margin);
}
body->setArea({0, 0, newDim.w, newDim.h});
return true;
};
}
void SMSInputWidget::handleDraftMessage()
{
const auto &text = inputText->getText();
text.empty() ? clearDraftMessage() : updateDraftMessage(text);
}
void SMSInputWidget::clearDraftMessage()
{
if (!draft.has_value()) {
displayDraftMessage();
return;
}
auto app = dynamic_cast<app::ApplicationMessages *>(application);
assert(app != nullptr);
if (const auto removed = app->removeDraft(draft.value()); removed) {
draft = std::nullopt;
displayDraftMessage();
}
}
void SMSInputWidget::displayDraftMessage() const
{
if (draft.has_value()) {
inputText->setText(draft->body);
}
else {
inputText->clear();
}
}
void SMSInputWidget::updateDraftMessage(const UTF8 &inputText)
{
auto app = dynamic_cast<app::ApplicationMessages *>(application);
assert(app != nullptr);
assert(number != nullptr);
if (draft.has_value()) {
app->updateDraft(draft.value(), inputText);
}
else {
app->createDraft(*number, inputText, [this](const SMSRecord &record) { draft = record; });
}
}
auto SMSInputWidget::handleRequestResize([[maybe_unused]] const Item *child, Length request_w, Length request_h)
-> Size
{
request_h =
std::clamp((Length)request_h, style::messages::smsInput::min_h, style::messages::smsInput::max_input_h);
setMinimumHeight(request_h);
if (parent != nullptr) {
requestSize(request_w, request_h);
}
return Size(request_w, request_h);
}
} /* namespace gui */