feat(chat): emoji picker + show-hidden toggle
- Emoji picker: a 🙂 button on the composer row opens a scrollable grid of ~150 common single-codepoint emoji (all verified present in the bundled NotoEmoji subset); clicking appends to the composer, respecting the byte cap. ImGui does no shaping, so the set is single-codepoint only (ZWJ sequences / flags omitted). - Show hidden: when there are hidden conversations, a "Show hidden (N)" toggle appears in the list; toggling it reveals them (dimmed) and the thread header's Hide button becomes Unhide. Off by default, and resets when nothing is hidden. 8-language strings; no new CJK glyphs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "Speichert die entschlüsselten Nachrichten als Klartext. Bewahre die Datei sicher auf.",
|
||||
"chat_hidden_toast": "Unterhaltung ausgeblendet – eine neue Nachricht holt sie zurück",
|
||||
"chat_hide": "Ausblenden",
|
||||
"chat_hide_hidden": "Ausgeblendete verbergen",
|
||||
"chat_jump_latest": "Neueste",
|
||||
"chat_len_over": "Nachricht zu lang",
|
||||
"chat_locked_hint": "Entsperre deine Wallet, um deine Chats zu laden.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "Senden",
|
||||
"chat_send_failed": "nicht gesendet",
|
||||
"chat_sending": "senden…",
|
||||
"chat_show_hidden": "Ausgeblendete anzeigen",
|
||||
"chat_time_now": "jetzt",
|
||||
"chat_toast_compose_failed": "Nachricht konnte nicht erstellt werden (zu lang?).",
|
||||
"chat_toast_lite_busy": "Es wird bereits gesendet, oder es ist keine Wallet geöffnet.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "Kontaktanfrage konnte nicht erstellt werden (ungültige Adresse / ungültiger Text?).",
|
||||
"chat_toast_request_queued": "Kontaktanfrage in Warteschlange.",
|
||||
"chat_toast_waiting_reply": "Warte auf die Antwort des Kontakts, bevor du ihm schreiben kannst.",
|
||||
"chat_unhide": "Einblenden",
|
||||
"chat_unmute": "Stummschaltung aufheben",
|
||||
"chat_waiting_reply": "Warte auf die Antwort dieses Kontakts – sobald er antwortet, kannst du ihm schreiben.",
|
||||
"chat_you": "Du",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "Guarda los mensajes descifrados como texto sin cifrar. Guarda el archivo de forma segura.",
|
||||
"chat_hidden_toast": "Conversación oculta: un mensaje nuevo la recupera",
|
||||
"chat_hide": "Ocultar",
|
||||
"chat_hide_hidden": "Ocultar ocultos",
|
||||
"chat_jump_latest": "Recientes",
|
||||
"chat_len_over": "Mensaje demasiado largo",
|
||||
"chat_locked_hint": "Desbloquea tu monedero para cargar tus chats.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "Enviar",
|
||||
"chat_send_failed": "no enviado",
|
||||
"chat_sending": "enviando…",
|
||||
"chat_show_hidden": "Ver ocultos",
|
||||
"chat_time_now": "ahora",
|
||||
"chat_toast_compose_failed": "No se pudo componer el mensaje (¿demasiado largo?).",
|
||||
"chat_toast_lite_busy": "Ya hay un envío en curso, o no hay ningún monedero abierto.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "No se pudo componer la solicitud de contacto (¿dirección o texto no válidos?).",
|
||||
"chat_toast_request_queued": "Solicitud de contacto en cola.",
|
||||
"chat_toast_waiting_reply": "Espera a que este contacto responda antes de poder escribirle.",
|
||||
"chat_unhide": "Mostrar",
|
||||
"chat_unmute": "Reactivar",
|
||||
"chat_waiting_reply": "Esperando a que este contacto responda: podrás escribirle una vez lo haga.",
|
||||
"chat_you": "Tú",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "Enregistre les messages déchiffrés en texte clair. Conservez le fichier en lieu sûr.",
|
||||
"chat_hidden_toast": "Conversation masquée — un nouveau message la fait réapparaître",
|
||||
"chat_hide": "Masquer",
|
||||
"chat_hide_hidden": "Masquer masqués",
|
||||
"chat_jump_latest": "Récents",
|
||||
"chat_len_over": "Message trop long",
|
||||
"chat_locked_hint": "Déverrouillez votre portefeuille pour charger vos discussions.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "Envoyer",
|
||||
"chat_send_failed": "non envoyé",
|
||||
"chat_sending": "envoi…",
|
||||
"chat_show_hidden": "Afficher masqués",
|
||||
"chat_time_now": "à l'instant",
|
||||
"chat_toast_compose_failed": "Impossible de composer le message (trop long ?).",
|
||||
"chat_toast_lite_busy": "Un envoi est déjà en cours, ou aucun portefeuille n'est ouvert.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "Impossible de composer la demande de contact (adresse / texte invalide ?).",
|
||||
"chat_toast_request_queued": "Demande de contact mise en file d'attente.",
|
||||
"chat_toast_waiting_reply": "En attente de la réponse de ce contact avant de pouvoir lui écrire.",
|
||||
"chat_unhide": "Afficher",
|
||||
"chat_unmute": "Réactiver",
|
||||
"chat_waiting_reply": "En attente de la réponse de ce contact — vous pourrez lui écrire dès qu'il aura répondu.",
|
||||
"chat_you": "Vous",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "復号したメッセージを平文で保存します。ファイルは安全に保管してください。",
|
||||
"chat_hidden_toast": "会話を非表示にしました — 新しいメッセージが届くと再表示されます",
|
||||
"chat_hide": "非表示",
|
||||
"chat_hide_hidden": "非表示を隠す",
|
||||
"chat_jump_latest": "最新",
|
||||
"chat_len_over": "メッセージが長すぎます",
|
||||
"chat_locked_hint": "チャットを読み込むにはウォレットのロックを解除してください。",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "送信",
|
||||
"chat_send_failed": "未送信",
|
||||
"chat_sending": "送信中…",
|
||||
"chat_show_hidden": "非表示を表示",
|
||||
"chat_time_now": "たった今",
|
||||
"chat_toast_compose_failed": "メッセージを作成できませんでした(長すぎませんか?)。",
|
||||
"chat_toast_lite_busy": "すでに送信処理が進行中か、ウォレットが開かれていません。",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "連絡リクエストを作成できませんでした(アドレスまたはテキストが無効?)。",
|
||||
"chat_toast_request_queued": "連絡リクエストを送信待ちに追加しました。",
|
||||
"chat_toast_waiting_reply": "メッセージを送るには、この相手からの返信を待つ必要があります。",
|
||||
"chat_unhide": "再表示",
|
||||
"chat_unmute": "ミュート解除",
|
||||
"chat_waiting_reply": "この相手からの返信を待っています — 返信があればメッセージを送れます。",
|
||||
"chat_you": "自分",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "복호화된 메시지를 일반 텍스트로 저장합니다. 파일을 안전하게 보관하세요.",
|
||||
"chat_hidden_toast": "대화를 숨겼습니다 — 새 메시지가 오면 다시 표시됩니다",
|
||||
"chat_hide": "숨기기",
|
||||
"chat_hide_hidden": "숨김 접기",
|
||||
"chat_jump_latest": "최신",
|
||||
"chat_len_over": "메시지가 너무 깁니다",
|
||||
"chat_locked_hint": "채팅을 불러오려면 지갑 잠금을 해제하세요.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "전송",
|
||||
"chat_send_failed": "전송 안 됨",
|
||||
"chat_sending": "전송 중…",
|
||||
"chat_show_hidden": "숨김 보기",
|
||||
"chat_time_now": "방금",
|
||||
"chat_toast_compose_failed": "메시지를 작성할 수 없습니다 (너무 긴가요?).",
|
||||
"chat_toast_lite_busy": "이미 전송이 진행 중이거나 열린 지갑이 없습니다.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "연락 요청을 작성할 수 없습니다 (잘못된 주소 / 텍스트?).",
|
||||
"chat_toast_request_queued": "연락 요청이 대기열에 추가되었습니다.",
|
||||
"chat_toast_waiting_reply": "상대방이 답장해야 메시지를 보낼 수 있습니다.",
|
||||
"chat_unhide": "다시 표시",
|
||||
"chat_unmute": "음소거 해제",
|
||||
"chat_waiting_reply": "상대방의 답장을 기다리는 중입니다 — 답장하면 메시지를 보낼 수 있습니다.",
|
||||
"chat_you": "나",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "Salva as mensagens descriptografadas como texto simples. Guarde o arquivo com segurança.",
|
||||
"chat_hidden_toast": "Conversa ocultada — uma nova mensagem a traz de volta",
|
||||
"chat_hide": "Ocultar",
|
||||
"chat_hide_hidden": "Ocultar ocultas",
|
||||
"chat_jump_latest": "Recentes",
|
||||
"chat_len_over": "Mensagem muito longa",
|
||||
"chat_locked_hint": "Desbloqueie sua carteira para carregar suas conversas.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "Enviar",
|
||||
"chat_send_failed": "não enviada",
|
||||
"chat_sending": "enviando…",
|
||||
"chat_show_hidden": "Ver ocultas",
|
||||
"chat_time_now": "agora",
|
||||
"chat_toast_compose_failed": "Não foi possível compor a mensagem (muito longa?).",
|
||||
"chat_toast_lite_busy": "Já há um envio em andamento, ou nenhuma carteira está aberta.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "Não foi possível compor a solicitação de contato (endereço / texto inválido?).",
|
||||
"chat_toast_request_queued": "Solicitação de contato na fila.",
|
||||
"chat_toast_waiting_reply": "Aguardando a resposta do contato antes que você possa enviar mensagens a ele.",
|
||||
"chat_unhide": "Mostrar",
|
||||
"chat_unmute": "Reativar som",
|
||||
"chat_waiting_reply": "Aguardando a resposta deste contato — você poderá enviar mensagens assim que ele responder.",
|
||||
"chat_you": "Você",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "Сохраняет расшифрованные сообщения в виде обычного текста. Храните файл в надёжном месте.",
|
||||
"chat_hidden_toast": "Разговор скрыт — новое сообщение вернёт его",
|
||||
"chat_hide": "Скрыть",
|
||||
"chat_hide_hidden": "Скрыть скрытые",
|
||||
"chat_jump_latest": "Новые",
|
||||
"chat_len_over": "Сообщение слишком длинное",
|
||||
"chat_locked_hint": "Разблокируйте кошелёк, чтобы загрузить переписку.",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "Отправить",
|
||||
"chat_send_failed": "не отправлено",
|
||||
"chat_sending": "отправка…",
|
||||
"chat_show_hidden": "Показать скрытые",
|
||||
"chat_time_now": "сейчас",
|
||||
"chat_toast_compose_failed": "Не удалось составить сообщение (слишком длинное?).",
|
||||
"chat_toast_lite_busy": "Отправка уже выполняется, или кошелёк не открыт.",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "Не удалось составить запрос контакта (неверный адрес / текст?).",
|
||||
"chat_toast_request_queued": "Запрос контакта поставлен в очередь.",
|
||||
"chat_toast_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему только после этого.",
|
||||
"chat_unhide": "Показать",
|
||||
"chat_unmute": "Включить уведомления",
|
||||
"chat_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему, как только он ответит.",
|
||||
"chat_you": "Вы",
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
"chat_export_warn": "将解密后的消息保存为纯文本。请妥善保管该文件。",
|
||||
"chat_hidden_toast": "会话已隐藏——收到新消息后会重新显示",
|
||||
"chat_hide": "隐藏",
|
||||
"chat_hide_hidden": "收起已隐藏",
|
||||
"chat_jump_latest": "最新",
|
||||
"chat_len_over": "消息过长",
|
||||
"chat_locked_hint": "解锁钱包以加载您的聊天记录。",
|
||||
@@ -167,6 +168,7 @@
|
||||
"chat_send": "发送",
|
||||
"chat_send_failed": "未发送",
|
||||
"chat_sending": "发送中…",
|
||||
"chat_show_hidden": "显示已隐藏",
|
||||
"chat_time_now": "刚刚",
|
||||
"chat_toast_compose_failed": "无法编写该消息(内容过长?)。",
|
||||
"chat_toast_lite_busy": "已有发送正在进行中,或未打开任何钱包。",
|
||||
@@ -176,6 +178,7 @@
|
||||
"chat_toast_request_compose_failed": "无法编写联系人请求(地址或文本无效?)。",
|
||||
"chat_toast_request_queued": "联系人请求已排队。",
|
||||
"chat_toast_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
||||
"chat_unhide": "取消隐藏",
|
||||
"chat_unmute": "取消静音",
|
||||
"chat_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
||||
"chat_you": "我",
|
||||
|
||||
@@ -48,6 +48,7 @@ bool s_show_new_convo = false;
|
||||
char s_new_zaddr[128] = "";
|
||||
char s_new_msg[256] = "";
|
||||
char s_search[80] = ""; // conversation-list filter (Q8)
|
||||
bool s_show_hidden = false; // when on, the list also shows hidden conversations (with an Unhide action)
|
||||
|
||||
// Effective draw-list font size for a material font (mirrors sidebar's ScaledFontSize).
|
||||
float scaledSize(ImFont* f) { return f->LegacySize * ImGui::GetStyle().FontScaleMain; }
|
||||
@@ -136,6 +137,7 @@ struct ConvSummary {
|
||||
std::string lastBody;
|
||||
std::int64_t lastTs = 0;
|
||||
int count = 0;
|
||||
bool hidden = false; // shown only while "Show hidden" is on
|
||||
};
|
||||
|
||||
// Centered, muted, wrapped hint for the empty states.
|
||||
@@ -199,6 +201,42 @@ void centeredEmptyState(const char* icon, const char* title, const char* hint) {
|
||||
}
|
||||
}
|
||||
|
||||
// Emoji picker popup: a scrollable grid of common single-codepoint emoji (verified present in the
|
||||
// bundled NotoEmoji subset). Clicking one appends its UTF-8 bytes to `buf` (respecting the buffer).
|
||||
// The set is single-codepoint only — ImGui does no shaping, so ZWJ sequences / flags wouldn't compose.
|
||||
void emojiPickerPopup(const char* popupId, char* buf, std::size_t bufSize) {
|
||||
static const char* const kEmoji =
|
||||
u8"😀😃😄😁😆😅😂🤣😊😇🙂🙃😉😌😍🥰😘😗😙😚😋😛😝😜🤪🤨🧐🤓😎🥳😏😒😞😔😟😕🙁😣😖😫😩🥺😢😭😤"
|
||||
u8"😠😡🤬🤯😳🥵🥶😱😨😰😥😓🤗🤔🤭🤫🤥😶😐😑😬🙄😯😦😧😮😲🥱😴🤤😪🤐🥴🤢🤮🤧😷🤒🤕😈👿💀👻👽🤖😺🙀"
|
||||
u8"👍👎👌✌🤞🤟🤘👏🙌👐🙏💪👋🤙👊✊🤛🤜👆👇👈👉"
|
||||
u8"❤🧡💛💚💙💜🖤🤍💔💕💞💗💖💘💝🔥⭐🎉🎊✨💯✅❌❓❗👀🎂🚀💰🎁🍺🍻☕🍕👑💎🌟💥";
|
||||
const float dp = Layout::dpiScale();
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, 260.0f * dp)); // cap height → scrolls
|
||||
if (!ImGui::BeginPopup(popupId)) return;
|
||||
ImGui::PushFont(material::Type().subtitle1()); // larger + emoji-capable
|
||||
const float cell = 30.0f * dp;
|
||||
const int perRow = 9;
|
||||
int idx = 0;
|
||||
for (const char* s = kEmoji; *s;) {
|
||||
const unsigned char lead = static_cast<unsigned char>(*s);
|
||||
const int len = (lead >= 0xF0) ? 4 : (lead >= 0xE0) ? 3 : (lead >= 0xC0) ? 2 : 1;
|
||||
char glyph[5] = {0};
|
||||
for (int k = 0; k < len && s[k]; ++k) glyph[k] = s[k];
|
||||
ImGui::PushID(idx);
|
||||
if (ImGui::Button(glyph, ImVec2(cell, cell))) {
|
||||
const std::size_t cur = std::strlen(buf);
|
||||
const std::size_t add = std::strlen(glyph);
|
||||
if (cur + add < bufSize) { std::memcpy(buf + cur, glyph, add); buf[cur + add] = '\0'; }
|
||||
}
|
||||
ImGui::PopID();
|
||||
if ((idx + 1) % perRow != 0) ImGui::SameLine();
|
||||
s += len;
|
||||
++idx;
|
||||
}
|
||||
ImGui::PopFont();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void RenderChatTab(App* app)
|
||||
@@ -215,12 +253,16 @@ void RenderChatTab(App* app)
|
||||
|
||||
// Build conversation summaries (single scan per conversation), sorted by most-recent activity.
|
||||
std::vector<ConvSummary> convs;
|
||||
int hiddenCount = 0;
|
||||
for (const auto& cid : store.conversationIds()) {
|
||||
if (app->settings() && app->settings()->isChatHidden(cid)) continue; // hidden — a new message un-hides it
|
||||
const bool hidden = app->settings() && app->settings()->isChatHidden(cid);
|
||||
if (hidden) ++hiddenCount;
|
||||
if (hidden && !s_show_hidden) continue; // filtered out unless "Show hidden" is on
|
||||
const auto messages = store.conversation(cid);
|
||||
if (messages.empty()) continue;
|
||||
ConvSummary c;
|
||||
c.cid = cid;
|
||||
c.hidden = hidden;
|
||||
c.count = static_cast<int>(messages.size());
|
||||
for (const auto& m : messages) { // pin to the EARLIEST (establishing) peer z-addr / key (B2 — the
|
||||
if (c.peerZaddr.empty() && !m.peer_zaddr.empty()) c.peerZaddr = m.peer_zaddr; // memo header rides
|
||||
@@ -285,6 +327,18 @@ void RenderChatTab(App* app)
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
ImGui::InputTextWithHint("##chatsearch", TR("chat_search"), s_search, sizeof(s_search));
|
||||
}
|
||||
// Show-hidden toggle — only when there are hidden conversations. Reveals them in the list (with
|
||||
// an Unhide action in the thread header).
|
||||
if (hiddenCount > 0) {
|
||||
ImGui::PushFont(metaFont);
|
||||
const std::string lbl = s_show_hidden
|
||||
? std::string(TR("chat_hide_hidden"))
|
||||
: std::string(TR("chat_show_hidden")) + " (" + std::to_string(hiddenCount) + ")";
|
||||
if (ImGui::SmallButton(lbl.c_str())) s_show_hidden = !s_show_hidden;
|
||||
ImGui::PopFont();
|
||||
} else {
|
||||
s_show_hidden = false; // nothing hidden → keep the toggle off
|
||||
}
|
||||
const std::string search = s_search;
|
||||
ImGui::Separator();
|
||||
if (convs.empty()) {
|
||||
@@ -335,8 +389,9 @@ void RenderChatTab(App* app)
|
||||
}
|
||||
const float textX = avC.x + avR + pad;
|
||||
|
||||
// Name (top).
|
||||
dl->AddText(nameFont, nameSz, ImVec2(textX, p.y + pad), material::OnSurface(), c.peerName.c_str());
|
||||
// Name (top). Hidden conversations (shown via "Show hidden") render dimmed.
|
||||
dl->AddText(nameFont, nameSz, ImVec2(textX, p.y + pad),
|
||||
c.hidden ? material::OnSurfaceMedium() : material::OnSurface(), c.peerName.c_str());
|
||||
// Time (top-right, muted) — compact relative form (Q5).
|
||||
const std::string when = relativeTime(c.lastTs);
|
||||
if (!when.empty()) {
|
||||
@@ -440,15 +495,20 @@ void RenderChatTab(App* app)
|
||||
app->settings()->setChatMuted(sel->cid, !muted);
|
||||
app->settings()->save();
|
||||
}
|
||||
// Hide conversation — drops it from the list (messages stay in the encrypted store; a
|
||||
// new incoming message brings it back). Deselect so the thread resets to the next one.
|
||||
// Hide / Unhide. Hiding drops it from the list (messages stay in the encrypted store);
|
||||
// Unhide (shown only for a hidden conversation while "Show hidden" is on) restores it.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(TR("chat_hide")) && app->settings()) {
|
||||
app->markChatConversationSeen(sel->cid, sel->lastTs); // don't leave a phantom unread
|
||||
app->settings()->setChatHidden(sel->cid, true);
|
||||
app->settings()->save();
|
||||
s_selected_cid.clear();
|
||||
Notifications::instance().info(TR("chat_hidden_toast"));
|
||||
if (ImGui::SmallButton(sel->hidden ? TR("chat_unhide") : TR("chat_hide")) && app->settings()) {
|
||||
if (sel->hidden) {
|
||||
app->settings()->setChatHidden(sel->cid, false);
|
||||
app->settings()->save();
|
||||
} else {
|
||||
app->markChatConversationSeen(sel->cid, sel->lastTs); // don't leave a phantom unread
|
||||
app->settings()->setChatHidden(sel->cid, true);
|
||||
app->settings()->save();
|
||||
s_selected_cid.clear();
|
||||
Notifications::instance().info(TR("chat_hidden_toast"));
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
@@ -596,6 +656,13 @@ void RenderChatTab(App* app)
|
||||
if (material::TactileButton(TR("chat_send"), ImVec2(sendW, composerBoxH))) submit = true;
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopStyleColor(3);
|
||||
// Emoji picker button (left) + byte counter (right) on one row.
|
||||
ImGui::PushFont(nameFont); // Body2 has emoji merged, so the glyph renders
|
||||
const bool emojiClicked = ImGui::SmallButton(u8"🙂");
|
||||
ImGui::PopFont();
|
||||
if (emojiClicked) ImGui::OpenPopup("##emojipick");
|
||||
emojiPickerPopup("##emojipick", s_compose, sizeof(s_compose));
|
||||
ImGui::SameLine();
|
||||
// Byte counter (Error tint over cap) with the over-cap label.
|
||||
ImGui::PushFont(metaFont);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, overCap ? material::Error() : material::OnSurfaceMedium());
|
||||
|
||||
@@ -253,6 +253,9 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["chat_mute"] = "Mute";
|
||||
strings_["chat_unmute"] = "Unmute";
|
||||
strings_["chat_hide"] = "Hide";
|
||||
strings_["chat_unhide"] = "Unhide";
|
||||
strings_["chat_show_hidden"] = "Show hidden";
|
||||
strings_["chat_hide_hidden"] = "Hide hidden";
|
||||
strings_["chat_hidden_toast"] = "Conversation hidden — a new message brings it back";
|
||||
strings_["chat_pick_contact"] = "Choose from contacts\xE2\x80\xA6";
|
||||
strings_["chat_no_z_contacts"] = "No shielded-address contacts yet";
|
||||
|
||||
Reference in New Issue
Block a user