Files
shinoa/src/app_help.cpp
Dmitry c6e2a43e4b
All checks were successful
Release App / release-app (push) Successful in 46s
Add saved GIF picker and docs
2026-04-26 12:50:18 +03:00

176 lines
5.3 KiB
C++

#include "app.h"
#include <algorithm>
#include <vector>
#include <curses.h>
#include "util.h"
namespace telegram_tui {
namespace {
const std::vector<std::string> kShinoaBanner = {
" ____ _ _ ", " / ___|| |__ (_)_ __ ___ __ _ ",
" \\___ \\| '_ \\| | '_ \\ / _ \\ / _` |", " ___) | | | | | | | | (_) | (_| |",
" |____/|_| |_|_|_| |_|\\___/ \\__,_|",
};
} // namespace
void App::handle_help_menu_key(int ch) {
switch (ch) {
case 27:
case 'h':
case '?':
case KEY_F(1):
help_menu_open_ = false;
status_line_ = "Closed help.";
return;
case '1':
help_menu_page_ = 0;
status_line_ = "Help.";
return;
case '2':
help_menu_page_ = 1;
status_line_ = "Settings.";
return;
case '3':
help_menu_page_ = 2;
status_line_ = "About.";
return;
case KEY_LEFT:
help_menu_page_ = (help_menu_page_ + 2) % 3;
return;
case KEY_RIGHT:
help_menu_page_ = (help_menu_page_ + 1) % 3;
return;
case 't':
if (help_menu_page_ != 1) {
return;
}
auto_reload_chat_history_ = !auto_reload_chat_history_;
persist_config();
status_line_ = auto_reload_chat_history_ ? "Auto-reload history enabled."
: "Auto-reload history disabled.";
return;
default:
return;
}
}
void App::draw_help_menu(int height, int width) {
const int menu_width = std::min(width - 4, 92);
const int menu_height = std::min(height - 4, 24);
const int top = std::max(1, (height - menu_height) / 2);
const int left = std::max(1, (width - menu_width) / 2);
WINDOW *window = newwin(menu_height, menu_width, top, left);
if (window == nullptr) {
return;
}
box(window, 0, 0);
const char *title =
help_menu_page_ == 0 ? " Help " : (help_menu_page_ == 1 ? " Settings " : " About ");
mvwprintw(window, 0, 2, "%s", title);
const std::string page_tabs =
help_menu_page_ == 0 ? "[1] Help 2 Settings 3 About"
: (help_menu_page_ == 1 ? "1 Help [2] Settings 3 About"
: "1 Help 2 Settings [3] About");
mvwaddnstr(window, 1, 2, page_tabs.c_str(), menu_width - 4);
mvwhline(window, 2, 1, ACS_HLINE, menu_width - 2);
const auto help_item = [](const std::string &key, const std::string &description) {
std::string line = " " + key;
const int key_width = std::max(16, utf8_display_width(key));
const int padding = std::max(2, key_width - utf8_display_width(key) + 2);
line.append(static_cast<std::size_t>(padding), ' ');
line += description;
return line;
};
std::vector<std::string> lines;
if (help_menu_page_ == 0) {
lines = {
"Navigation",
help_item("? / h", "Open or close help"),
help_item("Tab", "Switch focus"),
help_item("Enter", "Open selected chat"),
help_item("Up / Down", "Move chats or attachment selection"),
help_item("PgUp / PgDn", "Scroll messages"),
"",
"Compose",
help_item("i", "Compose a message"),
help_item("g", "Open saved GIF picker"),
help_item("a", "Prepare reply to latest"),
help_item(">r <msg> [text]", "Prepare a reply"),
help_item(">paste [caption]", "Send clipboard image"),
"",
"Message Actions",
help_item(">f <msg...>", "Forward messages"),
help_item(">e <msg> <text>", "Edit a message"),
help_item(">d <msg...>", "Delete your messages"),
help_item("m / o", "Attachments menu / open selected"),
};
} else if (help_menu_page_ == 1) {
lines = {
"Settings",
std::string(" [") + (auto_reload_chat_history_ ? 'x' : ' ') +
"] Auto-reload open chat history [t]",
"",
"Behavior",
" On: Enter in the message pane reloads history.",
" Off: Press r to reload the current chat manually.",
"",
"Menu",
help_item("1 / 2 / 3", "Switch help pages"),
help_item("Left / Right", "Cycle pages"),
help_item("Esc", "Close the help overlay"),
};
} else {
lines = {
"",
"",
};
}
const int content_top = 3;
const int content_height = menu_height - 6;
if (help_menu_page_ == 2) {
int row = content_top;
for (const auto &line : kShinoaBanner) {
if (row >= content_top + content_height) {
break;
}
const int x = std::max(2, (menu_width - static_cast<int>(line.size())) / 2);
mvwaddnstr(window, row++, x, line.c_str(), menu_width - x - 1);
}
const std::vector<std::string> about_lines = {
"",
"Telegram TUI with message refs, reply prep, attachment navigation,",
"and keyboard-first chat workflows.",
};
for (const auto &line : about_lines) {
if (row >= content_top + content_height) {
break;
}
const int x = std::max(2, (menu_width - static_cast<int>(line.size())) / 2);
mvwaddnstr(window, row++, x, line.c_str(), menu_width - x - 1);
}
} else {
for (std::size_t i = 0; i < lines.size() && static_cast<int>(i) < content_height;
++i) {
mvwaddnstr(window, static_cast<int>(i) + content_top, 2, lines[i].c_str(),
menu_width - 4);
}
}
mvwhline(window, menu_height - 3, 1, ACS_HLINE, menu_width - 2);
mvwaddnstr(window, menu_height - 2, 2, "Esc close", menu_width - 4);
wrefresh(window);
delwin(window);
}
} // namespace telegram_tui