Compare commits
3 Commits
3465acc57b
...
64b27db2ff
| Author | SHA1 | Date | |
|---|---|---|---|
| 64b27db2ff | |||
| 03fe6e077c | |||
| 125ffa8863 |
Binary file not shown.
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "Abbrechen",
|
"chat_cancel": "Abbrechen",
|
||||||
"chat_contact_added": "Kontakt hinzugefügt – benenne ihn in Kontakte um",
|
"chat_contact_added": "Kontakt hinzugefügt – benenne ihn in Kontakte um",
|
||||||
"chat_contact_request": "kontaktanfrage",
|
"chat_contact_request": "kontaktanfrage",
|
||||||
|
"chat_emoji_search": "Emoji suchen",
|
||||||
"chat_empty_hint": "Noch keine Unterhaltungen. Nachrichten, die du erhältst, erscheinen hier.",
|
"chat_empty_hint": "Noch keine Unterhaltungen. Nachrichten, die du erhältst, erscheinen hier.",
|
||||||
"chat_empty_start": "Starte eine mit \"Neue Unterhaltung\".",
|
"chat_empty_start": "Starte eine mit \"Neue Unterhaltung\".",
|
||||||
"chat_empty_title": "Noch keine Unterhaltungen",
|
"chat_empty_title": "Noch keine Unterhaltungen",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "Speichert die entschlüsselten Nachrichten als Klartext. Bewahre die Datei sicher auf.",
|
"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_hidden_toast": "Unterhaltung ausgeblendet – eine neue Nachricht holt sie zurück",
|
||||||
"chat_hide": "Ausblenden",
|
"chat_hide": "Ausblenden",
|
||||||
|
"chat_hide_hidden": "Ausgeblendete verbergen",
|
||||||
"chat_jump_latest": "Neueste",
|
"chat_jump_latest": "Neueste",
|
||||||
"chat_len_over": "Nachricht zu lang",
|
"chat_len_over": "Nachricht zu lang",
|
||||||
"chat_locked_hint": "Entsperre deine Wallet, um deine Chats zu laden.",
|
"chat_locked_hint": "Entsperre deine Wallet, um deine Chats zu laden.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "Senden",
|
"chat_send": "Senden",
|
||||||
"chat_send_failed": "nicht gesendet",
|
"chat_send_failed": "nicht gesendet",
|
||||||
"chat_sending": "senden…",
|
"chat_sending": "senden…",
|
||||||
|
"chat_show_hidden": "Ausgeblendete anzeigen",
|
||||||
"chat_time_now": "jetzt",
|
"chat_time_now": "jetzt",
|
||||||
"chat_toast_compose_failed": "Nachricht konnte nicht erstellt werden (zu lang?).",
|
"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.",
|
"chat_toast_lite_busy": "Es wird bereits gesendet, oder es ist keine Wallet geöffnet.",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "Kontaktanfrage konnte nicht erstellt werden (ungültige Adresse / ungültiger Text?).",
|
"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_request_queued": "Kontaktanfrage in Warteschlange.",
|
||||||
"chat_toast_waiting_reply": "Warte auf die Antwort des Kontakts, bevor du ihm schreiben kannst.",
|
"chat_toast_waiting_reply": "Warte auf die Antwort des Kontakts, bevor du ihm schreiben kannst.",
|
||||||
|
"chat_unhide": "Einblenden",
|
||||||
"chat_unmute": "Stummschaltung aufheben",
|
"chat_unmute": "Stummschaltung aufheben",
|
||||||
"chat_waiting_reply": "Warte auf die Antwort dieses Kontakts – sobald er antwortet, kannst du ihm schreiben.",
|
"chat_waiting_reply": "Warte auf die Antwort dieses Kontakts – sobald er antwortet, kannst du ihm schreiben.",
|
||||||
"chat_you": "Du",
|
"chat_you": "Du",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "Cancelar",
|
"chat_cancel": "Cancelar",
|
||||||
"chat_contact_added": "Contacto añadido: renómbralo en Contactos",
|
"chat_contact_added": "Contacto añadido: renómbralo en Contactos",
|
||||||
"chat_contact_request": "solicitud de contacto",
|
"chat_contact_request": "solicitud de contacto",
|
||||||
|
"chat_emoji_search": "Buscar emoji",
|
||||||
"chat_empty_hint": "Aún no hay conversaciones. Los mensajes que recibas aparecerán aquí.",
|
"chat_empty_hint": "Aún no hay conversaciones. Los mensajes que recibas aparecerán aquí.",
|
||||||
"chat_empty_start": "Inicia una con \"Nueva conversación\".",
|
"chat_empty_start": "Inicia una con \"Nueva conversación\".",
|
||||||
"chat_empty_title": "Aún no hay conversaciones",
|
"chat_empty_title": "Aún no hay conversaciones",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "Guarda los mensajes descifrados como texto sin cifrar. Guarda el archivo de forma segura.",
|
"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_hidden_toast": "Conversación oculta: un mensaje nuevo la recupera",
|
||||||
"chat_hide": "Ocultar",
|
"chat_hide": "Ocultar",
|
||||||
|
"chat_hide_hidden": "Ocultar ocultos",
|
||||||
"chat_jump_latest": "Recientes",
|
"chat_jump_latest": "Recientes",
|
||||||
"chat_len_over": "Mensaje demasiado largo",
|
"chat_len_over": "Mensaje demasiado largo",
|
||||||
"chat_locked_hint": "Desbloquea tu monedero para cargar tus chats.",
|
"chat_locked_hint": "Desbloquea tu monedero para cargar tus chats.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "Enviar",
|
"chat_send": "Enviar",
|
||||||
"chat_send_failed": "no enviado",
|
"chat_send_failed": "no enviado",
|
||||||
"chat_sending": "enviando…",
|
"chat_sending": "enviando…",
|
||||||
|
"chat_show_hidden": "Ver ocultos",
|
||||||
"chat_time_now": "ahora",
|
"chat_time_now": "ahora",
|
||||||
"chat_toast_compose_failed": "No se pudo componer el mensaje (¿demasiado largo?).",
|
"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.",
|
"chat_toast_lite_busy": "Ya hay un envío en curso, o no hay ningún monedero abierto.",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "No se pudo componer la solicitud de contacto (¿dirección o texto no válidos?).",
|
"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_request_queued": "Solicitud de contacto en cola.",
|
||||||
"chat_toast_waiting_reply": "Espera a que este contacto responda antes de poder escribirle.",
|
"chat_toast_waiting_reply": "Espera a que este contacto responda antes de poder escribirle.",
|
||||||
|
"chat_unhide": "Mostrar",
|
||||||
"chat_unmute": "Reactivar",
|
"chat_unmute": "Reactivar",
|
||||||
"chat_waiting_reply": "Esperando a que este contacto responda: podrás escribirle una vez lo haga.",
|
"chat_waiting_reply": "Esperando a que este contacto responda: podrás escribirle una vez lo haga.",
|
||||||
"chat_you": "Tú",
|
"chat_you": "Tú",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "Annuler",
|
"chat_cancel": "Annuler",
|
||||||
"chat_contact_added": "Contact ajouté — renommez-le dans Contacts",
|
"chat_contact_added": "Contact ajouté — renommez-le dans Contacts",
|
||||||
"chat_contact_request": "demande de contact",
|
"chat_contact_request": "demande de contact",
|
||||||
|
"chat_emoji_search": "Rechercher un emoji",
|
||||||
"chat_empty_hint": "Aucune conversation pour l'instant. Les messages que vous recevez apparaîtront ici.",
|
"chat_empty_hint": "Aucune conversation pour l'instant. Les messages que vous recevez apparaîtront ici.",
|
||||||
"chat_empty_start": "Commencez-en une avec « Nouvelle conversation ».",
|
"chat_empty_start": "Commencez-en une avec « Nouvelle conversation ».",
|
||||||
"chat_empty_title": "Aucune conversation pour l'instant",
|
"chat_empty_title": "Aucune conversation pour l'instant",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "Enregistre les messages déchiffrés en texte clair. Conservez le fichier en lieu sûr.",
|
"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_hidden_toast": "Conversation masquée — un nouveau message la fait réapparaître",
|
||||||
"chat_hide": "Masquer",
|
"chat_hide": "Masquer",
|
||||||
|
"chat_hide_hidden": "Masquer masqués",
|
||||||
"chat_jump_latest": "Récents",
|
"chat_jump_latest": "Récents",
|
||||||
"chat_len_over": "Message trop long",
|
"chat_len_over": "Message trop long",
|
||||||
"chat_locked_hint": "Déverrouillez votre portefeuille pour charger vos discussions.",
|
"chat_locked_hint": "Déverrouillez votre portefeuille pour charger vos discussions.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "Envoyer",
|
"chat_send": "Envoyer",
|
||||||
"chat_send_failed": "non envoyé",
|
"chat_send_failed": "non envoyé",
|
||||||
"chat_sending": "envoi…",
|
"chat_sending": "envoi…",
|
||||||
|
"chat_show_hidden": "Afficher masqués",
|
||||||
"chat_time_now": "à l'instant",
|
"chat_time_now": "à l'instant",
|
||||||
"chat_toast_compose_failed": "Impossible de composer le message (trop long ?).",
|
"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.",
|
"chat_toast_lite_busy": "Un envoi est déjà en cours, ou aucun portefeuille n'est ouvert.",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "Impossible de composer la demande de contact (adresse / texte invalide ?).",
|
"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_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_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_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_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",
|
"chat_you": "Vous",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "キャンセル",
|
"chat_cancel": "キャンセル",
|
||||||
"chat_contact_added": "連絡先を追加しました — 連絡先で名前を変更できます",
|
"chat_contact_added": "連絡先を追加しました — 連絡先で名前を変更できます",
|
||||||
"chat_contact_request": "連絡リクエスト",
|
"chat_contact_request": "連絡リクエスト",
|
||||||
|
"chat_emoji_search": "絵文字を検索",
|
||||||
"chat_empty_hint": "まだ会話はありません。受信したメッセージはここに表示されます。",
|
"chat_empty_hint": "まだ会話はありません。受信したメッセージはここに表示されます。",
|
||||||
"chat_empty_start": "「新しい会話」から始めましょう。",
|
"chat_empty_start": "「新しい会話」から始めましょう。",
|
||||||
"chat_empty_title": "会話はまだありません",
|
"chat_empty_title": "会話はまだありません",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "復号したメッセージを平文で保存します。ファイルは安全に保管してください。",
|
"chat_export_warn": "復号したメッセージを平文で保存します。ファイルは安全に保管してください。",
|
||||||
"chat_hidden_toast": "会話を非表示にしました — 新しいメッセージが届くと再表示されます",
|
"chat_hidden_toast": "会話を非表示にしました — 新しいメッセージが届くと再表示されます",
|
||||||
"chat_hide": "非表示",
|
"chat_hide": "非表示",
|
||||||
|
"chat_hide_hidden": "非表示を隠す",
|
||||||
"chat_jump_latest": "最新",
|
"chat_jump_latest": "最新",
|
||||||
"chat_len_over": "メッセージが長すぎます",
|
"chat_len_over": "メッセージが長すぎます",
|
||||||
"chat_locked_hint": "チャットを読み込むにはウォレットのロックを解除してください。",
|
"chat_locked_hint": "チャットを読み込むにはウォレットのロックを解除してください。",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "送信",
|
"chat_send": "送信",
|
||||||
"chat_send_failed": "未送信",
|
"chat_send_failed": "未送信",
|
||||||
"chat_sending": "送信中…",
|
"chat_sending": "送信中…",
|
||||||
|
"chat_show_hidden": "非表示を表示",
|
||||||
"chat_time_now": "たった今",
|
"chat_time_now": "たった今",
|
||||||
"chat_toast_compose_failed": "メッセージを作成できませんでした(長すぎませんか?)。",
|
"chat_toast_compose_failed": "メッセージを作成できませんでした(長すぎませんか?)。",
|
||||||
"chat_toast_lite_busy": "すでに送信処理が進行中か、ウォレットが開かれていません。",
|
"chat_toast_lite_busy": "すでに送信処理が進行中か、ウォレットが開かれていません。",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "連絡リクエストを作成できませんでした(アドレスまたはテキストが無効?)。",
|
"chat_toast_request_compose_failed": "連絡リクエストを作成できませんでした(アドレスまたはテキストが無効?)。",
|
||||||
"chat_toast_request_queued": "連絡リクエストを送信待ちに追加しました。",
|
"chat_toast_request_queued": "連絡リクエストを送信待ちに追加しました。",
|
||||||
"chat_toast_waiting_reply": "メッセージを送るには、この相手からの返信を待つ必要があります。",
|
"chat_toast_waiting_reply": "メッセージを送るには、この相手からの返信を待つ必要があります。",
|
||||||
|
"chat_unhide": "再表示",
|
||||||
"chat_unmute": "ミュート解除",
|
"chat_unmute": "ミュート解除",
|
||||||
"chat_waiting_reply": "この相手からの返信を待っています — 返信があればメッセージを送れます。",
|
"chat_waiting_reply": "この相手からの返信を待っています — 返信があればメッセージを送れます。",
|
||||||
"chat_you": "自分",
|
"chat_you": "自分",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "취소",
|
"chat_cancel": "취소",
|
||||||
"chat_contact_added": "연락처 추가됨 — 연락처에서 이름을 변경하세요",
|
"chat_contact_added": "연락처 추가됨 — 연락처에서 이름을 변경하세요",
|
||||||
"chat_contact_request": "연락 요청",
|
"chat_contact_request": "연락 요청",
|
||||||
|
"chat_emoji_search": "이모지 검색",
|
||||||
"chat_empty_hint": "아직 대화가 없습니다. 받은 메시지가 여기에 표시됩니다.",
|
"chat_empty_hint": "아직 대화가 없습니다. 받은 메시지가 여기에 표시됩니다.",
|
||||||
"chat_empty_start": "\"새 대화\"로 시작하세요.",
|
"chat_empty_start": "\"새 대화\"로 시작하세요.",
|
||||||
"chat_empty_title": "아직 대화가 없습니다",
|
"chat_empty_title": "아직 대화가 없습니다",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "복호화된 메시지를 일반 텍스트로 저장합니다. 파일을 안전하게 보관하세요.",
|
"chat_export_warn": "복호화된 메시지를 일반 텍스트로 저장합니다. 파일을 안전하게 보관하세요.",
|
||||||
"chat_hidden_toast": "대화를 숨겼습니다 — 새 메시지가 오면 다시 표시됩니다",
|
"chat_hidden_toast": "대화를 숨겼습니다 — 새 메시지가 오면 다시 표시됩니다",
|
||||||
"chat_hide": "숨기기",
|
"chat_hide": "숨기기",
|
||||||
|
"chat_hide_hidden": "숨김 접기",
|
||||||
"chat_jump_latest": "최신",
|
"chat_jump_latest": "최신",
|
||||||
"chat_len_over": "메시지가 너무 깁니다",
|
"chat_len_over": "메시지가 너무 깁니다",
|
||||||
"chat_locked_hint": "채팅을 불러오려면 지갑 잠금을 해제하세요.",
|
"chat_locked_hint": "채팅을 불러오려면 지갑 잠금을 해제하세요.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "전송",
|
"chat_send": "전송",
|
||||||
"chat_send_failed": "전송 안 됨",
|
"chat_send_failed": "전송 안 됨",
|
||||||
"chat_sending": "전송 중…",
|
"chat_sending": "전송 중…",
|
||||||
|
"chat_show_hidden": "숨김 보기",
|
||||||
"chat_time_now": "방금",
|
"chat_time_now": "방금",
|
||||||
"chat_toast_compose_failed": "메시지를 작성할 수 없습니다 (너무 긴가요?).",
|
"chat_toast_compose_failed": "메시지를 작성할 수 없습니다 (너무 긴가요?).",
|
||||||
"chat_toast_lite_busy": "이미 전송이 진행 중이거나 열린 지갑이 없습니다.",
|
"chat_toast_lite_busy": "이미 전송이 진행 중이거나 열린 지갑이 없습니다.",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "연락 요청을 작성할 수 없습니다 (잘못된 주소 / 텍스트?).",
|
"chat_toast_request_compose_failed": "연락 요청을 작성할 수 없습니다 (잘못된 주소 / 텍스트?).",
|
||||||
"chat_toast_request_queued": "연락 요청이 대기열에 추가되었습니다.",
|
"chat_toast_request_queued": "연락 요청이 대기열에 추가되었습니다.",
|
||||||
"chat_toast_waiting_reply": "상대방이 답장해야 메시지를 보낼 수 있습니다.",
|
"chat_toast_waiting_reply": "상대방이 답장해야 메시지를 보낼 수 있습니다.",
|
||||||
|
"chat_unhide": "다시 표시",
|
||||||
"chat_unmute": "음소거 해제",
|
"chat_unmute": "음소거 해제",
|
||||||
"chat_waiting_reply": "상대방의 답장을 기다리는 중입니다 — 답장하면 메시지를 보낼 수 있습니다.",
|
"chat_waiting_reply": "상대방의 답장을 기다리는 중입니다 — 답장하면 메시지를 보낼 수 있습니다.",
|
||||||
"chat_you": "나",
|
"chat_you": "나",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "Cancelar",
|
"chat_cancel": "Cancelar",
|
||||||
"chat_contact_added": "Contato adicionado — renomeie em Contatos",
|
"chat_contact_added": "Contato adicionado — renomeie em Contatos",
|
||||||
"chat_contact_request": "solicitação de contato",
|
"chat_contact_request": "solicitação de contato",
|
||||||
|
"chat_emoji_search": "Pesquisar emoji",
|
||||||
"chat_empty_hint": "Nenhuma conversa ainda. As mensagens que você receber aparecerão aqui.",
|
"chat_empty_hint": "Nenhuma conversa ainda. As mensagens que você receber aparecerão aqui.",
|
||||||
"chat_empty_start": "Inicie uma com \"Nova conversa\".",
|
"chat_empty_start": "Inicie uma com \"Nova conversa\".",
|
||||||
"chat_empty_title": "Ainda não há conversas",
|
"chat_empty_title": "Ainda não há conversas",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "Salva as mensagens descriptografadas como texto simples. Guarde o arquivo com segurança.",
|
"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_hidden_toast": "Conversa ocultada — uma nova mensagem a traz de volta",
|
||||||
"chat_hide": "Ocultar",
|
"chat_hide": "Ocultar",
|
||||||
|
"chat_hide_hidden": "Ocultar ocultas",
|
||||||
"chat_jump_latest": "Recentes",
|
"chat_jump_latest": "Recentes",
|
||||||
"chat_len_over": "Mensagem muito longa",
|
"chat_len_over": "Mensagem muito longa",
|
||||||
"chat_locked_hint": "Desbloqueie sua carteira para carregar suas conversas.",
|
"chat_locked_hint": "Desbloqueie sua carteira para carregar suas conversas.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "Enviar",
|
"chat_send": "Enviar",
|
||||||
"chat_send_failed": "não enviada",
|
"chat_send_failed": "não enviada",
|
||||||
"chat_sending": "enviando…",
|
"chat_sending": "enviando…",
|
||||||
|
"chat_show_hidden": "Ver ocultas",
|
||||||
"chat_time_now": "agora",
|
"chat_time_now": "agora",
|
||||||
"chat_toast_compose_failed": "Não foi possível compor a mensagem (muito longa?).",
|
"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.",
|
"chat_toast_lite_busy": "Já há um envio em andamento, ou nenhuma carteira está aberta.",
|
||||||
@@ -176,6 +179,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_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_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_toast_waiting_reply": "Aguardando a resposta do contato antes que você possa enviar mensagens a ele.",
|
||||||
|
"chat_unhide": "Mostrar",
|
||||||
"chat_unmute": "Reativar som",
|
"chat_unmute": "Reativar som",
|
||||||
"chat_waiting_reply": "Aguardando a resposta deste contato — você poderá enviar mensagens assim que ele responder.",
|
"chat_waiting_reply": "Aguardando a resposta deste contato — você poderá enviar mensagens assim que ele responder.",
|
||||||
"chat_you": "Você",
|
"chat_you": "Você",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "Отмена",
|
"chat_cancel": "Отмена",
|
||||||
"chat_contact_added": "Контакт добавлен — переименуйте его в Контактах",
|
"chat_contact_added": "Контакт добавлен — переименуйте его в Контактах",
|
||||||
"chat_contact_request": "запрос контакта",
|
"chat_contact_request": "запрос контакта",
|
||||||
|
"chat_emoji_search": "Поиск эмодзи",
|
||||||
"chat_empty_hint": "Пока нет переписок. Полученные сообщения появятся здесь.",
|
"chat_empty_hint": "Пока нет переписок. Полученные сообщения появятся здесь.",
|
||||||
"chat_empty_start": "Начните новый с помощью «Новый разговор».",
|
"chat_empty_start": "Начните новый с помощью «Новый разговор».",
|
||||||
"chat_empty_title": "Пока нет разговоров",
|
"chat_empty_title": "Пока нет разговоров",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "Сохраняет расшифрованные сообщения в виде обычного текста. Храните файл в надёжном месте.",
|
"chat_export_warn": "Сохраняет расшифрованные сообщения в виде обычного текста. Храните файл в надёжном месте.",
|
||||||
"chat_hidden_toast": "Разговор скрыт — новое сообщение вернёт его",
|
"chat_hidden_toast": "Разговор скрыт — новое сообщение вернёт его",
|
||||||
"chat_hide": "Скрыть",
|
"chat_hide": "Скрыть",
|
||||||
|
"chat_hide_hidden": "Скрыть скрытые",
|
||||||
"chat_jump_latest": "Новые",
|
"chat_jump_latest": "Новые",
|
||||||
"chat_len_over": "Сообщение слишком длинное",
|
"chat_len_over": "Сообщение слишком длинное",
|
||||||
"chat_locked_hint": "Разблокируйте кошелёк, чтобы загрузить переписку.",
|
"chat_locked_hint": "Разблокируйте кошелёк, чтобы загрузить переписку.",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "Отправить",
|
"chat_send": "Отправить",
|
||||||
"chat_send_failed": "не отправлено",
|
"chat_send_failed": "не отправлено",
|
||||||
"chat_sending": "отправка…",
|
"chat_sending": "отправка…",
|
||||||
|
"chat_show_hidden": "Показать скрытые",
|
||||||
"chat_time_now": "сейчас",
|
"chat_time_now": "сейчас",
|
||||||
"chat_toast_compose_failed": "Не удалось составить сообщение (слишком длинное?).",
|
"chat_toast_compose_failed": "Не удалось составить сообщение (слишком длинное?).",
|
||||||
"chat_toast_lite_busy": "Отправка уже выполняется, или кошелёк не открыт.",
|
"chat_toast_lite_busy": "Отправка уже выполняется, или кошелёк не открыт.",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "Не удалось составить запрос контакта (неверный адрес / текст?).",
|
"chat_toast_request_compose_failed": "Не удалось составить запрос контакта (неверный адрес / текст?).",
|
||||||
"chat_toast_request_queued": "Запрос контакта поставлен в очередь.",
|
"chat_toast_request_queued": "Запрос контакта поставлен в очередь.",
|
||||||
"chat_toast_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему только после этого.",
|
"chat_toast_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему только после этого.",
|
||||||
|
"chat_unhide": "Показать",
|
||||||
"chat_unmute": "Включить уведомления",
|
"chat_unmute": "Включить уведомления",
|
||||||
"chat_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему, как только он ответит.",
|
"chat_waiting_reply": "Ожидание ответа от контакта — вы сможете писать ему, как только он ответит.",
|
||||||
"chat_you": "Вы",
|
"chat_you": "Вы",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@
|
|||||||
"chat_cancel": "取消",
|
"chat_cancel": "取消",
|
||||||
"chat_contact_added": "已添加联系人——可在联系人中重命名",
|
"chat_contact_added": "已添加联系人——可在联系人中重命名",
|
||||||
"chat_contact_request": "联系人请求",
|
"chat_contact_request": "联系人请求",
|
||||||
|
"chat_emoji_search": "搜索表情",
|
||||||
"chat_empty_hint": "暂无对话。您收到的消息将显示在此处。",
|
"chat_empty_hint": "暂无对话。您收到的消息将显示在此处。",
|
||||||
"chat_empty_start": "点击\"新建会话\"开始。",
|
"chat_empty_start": "点击\"新建会话\"开始。",
|
||||||
"chat_empty_title": "还没有会话",
|
"chat_empty_title": "还没有会话",
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
"chat_export_warn": "将解密后的消息保存为纯文本。请妥善保管该文件。",
|
"chat_export_warn": "将解密后的消息保存为纯文本。请妥善保管该文件。",
|
||||||
"chat_hidden_toast": "会话已隐藏——收到新消息后会重新显示",
|
"chat_hidden_toast": "会话已隐藏——收到新消息后会重新显示",
|
||||||
"chat_hide": "隐藏",
|
"chat_hide": "隐藏",
|
||||||
|
"chat_hide_hidden": "收起已隐藏",
|
||||||
"chat_jump_latest": "最新",
|
"chat_jump_latest": "最新",
|
||||||
"chat_len_over": "消息过长",
|
"chat_len_over": "消息过长",
|
||||||
"chat_locked_hint": "解锁钱包以加载您的聊天记录。",
|
"chat_locked_hint": "解锁钱包以加载您的聊天记录。",
|
||||||
@@ -167,6 +169,7 @@
|
|||||||
"chat_send": "发送",
|
"chat_send": "发送",
|
||||||
"chat_send_failed": "未发送",
|
"chat_send_failed": "未发送",
|
||||||
"chat_sending": "发送中…",
|
"chat_sending": "发送中…",
|
||||||
|
"chat_show_hidden": "显示已隐藏",
|
||||||
"chat_time_now": "刚刚",
|
"chat_time_now": "刚刚",
|
||||||
"chat_toast_compose_failed": "无法编写该消息(内容过长?)。",
|
"chat_toast_compose_failed": "无法编写该消息(内容过长?)。",
|
||||||
"chat_toast_lite_busy": "已有发送正在进行中,或未打开任何钱包。",
|
"chat_toast_lite_busy": "已有发送正在进行中,或未打开任何钱包。",
|
||||||
@@ -176,6 +179,7 @@
|
|||||||
"chat_toast_request_compose_failed": "无法编写联系人请求(地址或文本无效?)。",
|
"chat_toast_request_compose_failed": "无法编写联系人请求(地址或文本无效?)。",
|
||||||
"chat_toast_request_queued": "联系人请求已排队。",
|
"chat_toast_request_queued": "联系人请求已排队。",
|
||||||
"chat_toast_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
"chat_toast_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
||||||
|
"chat_unhide": "取消隐藏",
|
||||||
"chat_unmute": "取消静音",
|
"chat_unmute": "取消静音",
|
||||||
"chat_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
"chat_waiting_reply": "等待该联系人回复——对方回复后您即可向其发送消息。",
|
||||||
"chat_you": "我",
|
"chat_you": "我",
|
||||||
|
|||||||
10
src/app.cpp
10
src/app.cpp
@@ -1168,8 +1168,14 @@ void App::update()
|
|||||||
} else if (walletDataPage && shouldRefreshRecentTransactions()) {
|
} else if (walletDataPage && shouldRefreshRecentTransactions()) {
|
||||||
refreshRecentTransactionData();
|
refreshRecentTransactionData();
|
||||||
}
|
}
|
||||||
// 0-conf chat: the normal harvest above only re-scans on a new block, so also do a light
|
}
|
||||||
// mempool scan of the chat address every cycle to surface messages before confirmation.
|
// 0-conf chat: a DEDICATED ~2.5s mempool scan of the chat address, independent of the page's
|
||||||
|
// (slower, 10–15s) Transactions cadence — so incoming messages surface in a few seconds. The
|
||||||
|
// normal harvest only re-scans on a new block. Self-gated (no-op without a chat identity /
|
||||||
|
// connection / on lite); the in-flight guard keeps overlapping RPCs from stacking.
|
||||||
|
chat_fast_scan_accum_ += ImGui::GetIO().DeltaTime;
|
||||||
|
if (chat_fast_scan_accum_ >= 2.5f) {
|
||||||
|
chat_fast_scan_accum_ = 0.0f;
|
||||||
fastScanChatMemos();
|
fastScanChatMemos();
|
||||||
}
|
}
|
||||||
if (network_refresh_.consumeDue(RefreshTimer::Addresses)) {
|
if (network_refresh_.consumeDue(RefreshTimer::Addresses)) {
|
||||||
|
|||||||
@@ -735,6 +735,7 @@ private:
|
|||||||
// (they still un-hide via the normal confirmed harvest). Self-gated; no-op without a chat identity.
|
// (they still un-hide via the normal confirmed harvest). Self-gated; no-op without a chat identity.
|
||||||
void fastScanChatMemos();
|
void fastScanChatMemos();
|
||||||
bool chat_fast_scan_in_flight_ = false; // guard against overlapping fast-scan RPCs
|
bool chat_fast_scan_in_flight_ = false; // guard against overlapping fast-scan RPCs
|
||||||
|
float chat_fast_scan_accum_ = 0.0f; // seconds since the last fast-scan (dedicated ~2.5s poll)
|
||||||
// Lite first-run welcome prompt: dismissed for the session once the user picks an action.
|
// Lite first-run welcome prompt: dismissed for the session once the user picks an action.
|
||||||
bool lite_firstrun_dismissed_ = false;
|
bool lite_firstrun_dismissed_ = false;
|
||||||
// Lite send-time unlock: set to show the unlock modal when a spend is attempted while locked.
|
// Lite send-time unlock: set to show the unlock modal when a spend is attempted while locked.
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ bool s_show_new_convo = false;
|
|||||||
char s_new_zaddr[128] = "";
|
char s_new_zaddr[128] = "";
|
||||||
char s_new_msg[256] = "";
|
char s_new_msg[256] = "";
|
||||||
char s_search[80] = ""; // conversation-list filter (Q8)
|
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)
|
||||||
|
bool s_show_emoji_picker = false; // emoji picker overlay — fills the conversation-list pane while open
|
||||||
|
char s_emoji_search[48] = ""; // emoji picker keyword filter
|
||||||
|
|
||||||
// Effective draw-list font size for a material font (mirrors sidebar's ScaledFontSize).
|
// Effective draw-list font size for a material font (mirrors sidebar's ScaledFontSize).
|
||||||
float scaledSize(ImFont* f) { return f->LegacySize * ImGui::GetStyle().FontScaleMain; }
|
float scaledSize(ImFont* f) { return f->LegacySize * ImGui::GetStyle().FontScaleMain; }
|
||||||
@@ -136,6 +139,7 @@ struct ConvSummary {
|
|||||||
std::string lastBody;
|
std::string lastBody;
|
||||||
std::int64_t lastTs = 0;
|
std::int64_t lastTs = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
bool hidden = false; // shown only while "Show hidden" is on
|
||||||
};
|
};
|
||||||
|
|
||||||
// Centered, muted, wrapped hint for the empty states.
|
// Centered, muted, wrapped hint for the empty states.
|
||||||
@@ -199,6 +203,77 @@ void centeredEmptyState(const char* icon, const char* title, const char* hint) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Common single-codepoint emoji (all verified present in the bundled NotoEmoji subset), each with
|
||||||
|
// keyword text for the picker's search box. Single-codepoint only — ImGui does no shaping, so ZWJ
|
||||||
|
// sequences / flags wouldn't compose.
|
||||||
|
struct EmojiEntry { const char* glyph; const char* keywords; };
|
||||||
|
static const EmojiEntry kEmoji[] = {
|
||||||
|
{u8"😀","grin happy smile"},{u8"😃","smile happy joy"},{u8"😄","laugh happy smile"},{u8"😁","grin beam happy"},
|
||||||
|
{u8"😆","laugh haha"},{u8"😅","sweat laugh nervous"},{u8"😂","joy laugh tears cry funny"},{u8"🤣","rofl laugh rolling funny"},
|
||||||
|
{u8"😊","blush smile happy"},{u8"😇","angel innocent halo"},{u8"🙂","slight smile"},{u8"🙃","upside down silly"},
|
||||||
|
{u8"😉","wink"},{u8"😌","relieved calm"},{u8"😍","heart eyes love"},{u8"🥰","love hearts adore"},{u8"😘","kiss blow"},
|
||||||
|
{u8"😗","kiss"},{u8"😙","kiss smile"},{u8"😚","kiss closed"},{u8"😋","yum tasty tongue"},{u8"😛","tongue playful"},
|
||||||
|
{u8"😝","tongue squint"},{u8"😜","wink tongue crazy"},{u8"🤪","zany crazy silly"},{u8"🤨","raised eyebrow suspicious"},
|
||||||
|
{u8"🧐","monocle thinking"},{u8"🤓","nerd geek glasses"},{u8"😎","cool sunglasses"},{u8"🥳","party celebrate hat"},
|
||||||
|
{u8"😏","smirk"},{u8"😒","unamused meh"},{u8"😞","disappointed sad"},{u8"😔","pensive sad"},{u8"😟","worried"},
|
||||||
|
{u8"😕","confused"},{u8"🙁","frown sad"},{u8"😣","persevere"},{u8"😖","confounded"},{u8"😫","tired"},{u8"😩","weary"},
|
||||||
|
{u8"🥺","pleading puppy beg"},{u8"😢","cry sad tear"},{u8"😭","sob cry bawl"},{u8"😤","huff triumph steam"},
|
||||||
|
{u8"😠","angry mad"},{u8"😡","rage mad angry"},{u8"🤬","curse swear angry"},{u8"🤯","mind blown shock"},
|
||||||
|
{u8"😳","flushed embarrassed"},{u8"🥵","hot heat sweat"},{u8"🥶","cold freezing"},{u8"😱","scream fear shock"},
|
||||||
|
{u8"😨","fearful scared"},{u8"😰","anxious sweat"},{u8"😥","sad sweat"},{u8"😓","sweat"},{u8"🤗","hug"},
|
||||||
|
{u8"🤔","think hmm"},{u8"🤭","giggle oops hand"},{u8"🤫","shush quiet"},{u8"🤥","lie"},{u8"😶","no mouth blank"},
|
||||||
|
{u8"😐","neutral meh"},{u8"😑","expressionless"},{u8"😬","grimace awkward"},{u8"🙄","eye roll"},{u8"😯","hushed surprise"},
|
||||||
|
{u8"😦","frown open"},{u8"😧","anguished"},{u8"😮","wow surprise oh"},{u8"😲","astonished shock"},{u8"🥱","yawn tired bored"},
|
||||||
|
{u8"😴","sleep zzz"},{u8"🤤","drool"},{u8"😪","sleepy"},{u8"🤐","zipper quiet secret"},{u8"🥴","woozy dizzy drunk"},
|
||||||
|
{u8"🤢","nausea sick"},{u8"🤮","vomit sick"},{u8"🤧","sneeze sick"},{u8"😷","mask sick"},{u8"🤒","sick thermometer"},
|
||||||
|
{u8"🤕","hurt bandage injured"},{u8"😈","devil imp evil"},{u8"👿","devil angry"},{u8"💀","skull dead"},{u8"👻","ghost boo"},
|
||||||
|
{u8"👽","alien"},{u8"🤖","robot bot"},{u8"😺","cat smile"},{u8"🙀","cat scream"},
|
||||||
|
{u8"👍","thumbs up like yes good"},{u8"👎","thumbs down dislike no bad"},{u8"👌","ok perfect"},{u8"✌","peace victory"},
|
||||||
|
{u8"🤞","fingers crossed luck"},{u8"🤟","love you"},{u8"🤘","rock horns"},{u8"👏","clap applause"},
|
||||||
|
{u8"🙌","raise hands celebrate"},{u8"👐","open hands"},{u8"🙏","pray thanks please"},{u8"💪","muscle strong flex"},
|
||||||
|
{u8"👋","wave hi hello bye"},{u8"🤙","call shaka"},{u8"👊","fist punch bump"},{u8"✊","fist raised"},{u8"🤛","fist left"},
|
||||||
|
{u8"🤜","fist right"},{u8"👆","up point"},{u8"👇","down point"},{u8"👈","left point"},{u8"👉","right point"},
|
||||||
|
{u8"❤","heart red love"},{u8"🧡","heart orange"},{u8"💛","heart yellow"},{u8"💚","heart green"},{u8"💙","heart blue"},
|
||||||
|
{u8"💜","heart purple"},{u8"🖤","heart black"},{u8"🤍","heart white"},{u8"💔","broken heart"},{u8"💕","hearts love"},
|
||||||
|
{u8"💞","revolving hearts"},{u8"💗","growing heart"},{u8"💖","sparkling heart"},{u8"💘","heart arrow cupid"},
|
||||||
|
{u8"💝","heart gift ribbon"},{u8"🔥","fire lit hot flame"},{u8"⭐","star"},{u8"🎉","party tada celebrate confetti"},
|
||||||
|
{u8"🎊","confetti party"},{u8"✨","sparkles shiny"},{u8"💯","hundred perfect 100"},{u8"✅","check yes done tick"},
|
||||||
|
{u8"❌","cross no wrong x"},{u8"❓","question mark"},{u8"❗","exclamation mark"},{u8"👀","eyes look"},{u8"🎂","cake birthday"},
|
||||||
|
{u8"🚀","rocket launch"},{u8"💰","money bag cash"},{u8"🎁","gift present"},{u8"🍺","beer"},{u8"🍻","beers cheers"},
|
||||||
|
{u8"☕","coffee tea"},{u8"🍕","pizza"},{u8"👑","crown king queen"},{u8"💎","diamond gem"},{u8"🌟","glowing star"},
|
||||||
|
{u8"💥","boom explosion"},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Emoji picker overlay: fills the conversation-list pane (cancel + keyword search at the top, then a
|
||||||
|
// grid). Clicking an emoji appends its UTF-8 bytes to `buf` (the composer), respecting the buffer.
|
||||||
|
void renderEmojiPickerOverlay(char* buf, std::size_t bufSize) {
|
||||||
|
if (ImGui::SmallButton(TR("chat_cancel"))) { s_show_emoji_picker = false; s_emoji_search[0] = '\0'; return; }
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||||
|
ImGui::InputTextWithHint("##emojisearch", TR("chat_emoji_search"), s_emoji_search, sizeof(s_emoji_search));
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
const std::string q = s_emoji_search;
|
||||||
|
ImGui::BeginChild("##emojigrid", ImVec2(0, 0), false);
|
||||||
|
ImGui::PushFont(material::Type().subtitle1()); // larger + emoji-capable
|
||||||
|
const float cell = 32.0f * Layout::dpiScale();
|
||||||
|
const float step = cell + ImGui::GetStyle().ItemSpacing.x;
|
||||||
|
const int perRow = std::max(1, static_cast<int>(ImGui::GetContentRegionAvail().x / step));
|
||||||
|
int shown = 0;
|
||||||
|
for (const auto& e : kEmoji) {
|
||||||
|
if (!q.empty() && !containsCI(e.keywords, q)) continue;
|
||||||
|
ImGui::PushID(shown);
|
||||||
|
if (ImGui::Button(e.glyph, ImVec2(cell, cell))) {
|
||||||
|
const std::size_t cur = std::strlen(buf), add = std::strlen(e.glyph);
|
||||||
|
if (cur + add < bufSize) { std::memcpy(buf + cur, e.glyph, add); buf[cur + add] = '\0'; }
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
if (++shown % perRow != 0) ImGui::SameLine();
|
||||||
|
}
|
||||||
|
ImGui::PopFont();
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void RenderChatTab(App* app)
|
void RenderChatTab(App* app)
|
||||||
@@ -215,12 +290,16 @@ void RenderChatTab(App* app)
|
|||||||
|
|
||||||
// Build conversation summaries (single scan per conversation), sorted by most-recent activity.
|
// Build conversation summaries (single scan per conversation), sorted by most-recent activity.
|
||||||
std::vector<ConvSummary> convs;
|
std::vector<ConvSummary> convs;
|
||||||
|
int hiddenCount = 0;
|
||||||
for (const auto& cid : store.conversationIds()) {
|
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);
|
const auto messages = store.conversation(cid);
|
||||||
if (messages.empty()) continue;
|
if (messages.empty()) continue;
|
||||||
ConvSummary c;
|
ConvSummary c;
|
||||||
c.cid = cid;
|
c.cid = cid;
|
||||||
|
c.hidden = hidden;
|
||||||
c.count = static_cast<int>(messages.size());
|
c.count = static_cast<int>(messages.size());
|
||||||
for (const auto& m : messages) { // pin to the EARLIEST (establishing) peer z-addr / key (B2 — the
|
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
|
if (c.peerZaddr.empty() && !m.peer_zaddr.empty()) c.peerZaddr = m.peer_zaddr; // memo header rides
|
||||||
@@ -268,7 +347,10 @@ void RenderChatTab(App* app)
|
|||||||
// Faint sidebar tint so the list reads as distinct from the thread pane (V6).
|
// Faint sidebar tint so the list reads as distinct from the thread pane (V6).
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(material::WithAlpha(material::OnSurface(), 10)));
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(material::WithAlpha(material::OnSurface(), 10)));
|
||||||
ImGui::BeginChild("##ChatList", ImVec2(listW, avail.y), true);
|
ImGui::BeginChild("##ChatList", ImVec2(listW, avail.y), true);
|
||||||
{
|
if (s_show_emoji_picker) {
|
||||||
|
// Emoji picker overlay takes over the conversation-list pane while open (search + cancel + grid).
|
||||||
|
renderEmojiPickerOverlay(s_compose, sizeof(s_compose));
|
||||||
|
} else {
|
||||||
// Accented "New conversation" action (house tactile style).
|
// Accented "New conversation" action (house tactile style).
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(material::WithAlpha(material::Primary(), 205)));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(material::WithAlpha(material::Primary(), 205)));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(material::Primary()));
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(material::Primary()));
|
||||||
@@ -285,6 +367,18 @@ void RenderChatTab(App* app)
|
|||||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||||
ImGui::InputTextWithHint("##chatsearch", TR("chat_search"), s_search, sizeof(s_search));
|
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;
|
const std::string search = s_search;
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (convs.empty()) {
|
if (convs.empty()) {
|
||||||
@@ -335,8 +429,9 @@ void RenderChatTab(App* app)
|
|||||||
}
|
}
|
||||||
const float textX = avC.x + avR + pad;
|
const float textX = avC.x + avR + pad;
|
||||||
|
|
||||||
// Name (top).
|
// Name (top). Hidden conversations (shown via "Show hidden") render dimmed.
|
||||||
dl->AddText(nameFont, nameSz, ImVec2(textX, p.y + pad), material::OnSurface(), c.peerName.c_str());
|
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).
|
// Time (top-right, muted) — compact relative form (Q5).
|
||||||
const std::string when = relativeTime(c.lastTs);
|
const std::string when = relativeTime(c.lastTs);
|
||||||
if (!when.empty()) {
|
if (!when.empty()) {
|
||||||
@@ -440,15 +535,20 @@ void RenderChatTab(App* app)
|
|||||||
app->settings()->setChatMuted(sel->cid, !muted);
|
app->settings()->setChatMuted(sel->cid, !muted);
|
||||||
app->settings()->save();
|
app->settings()->save();
|
||||||
}
|
}
|
||||||
// Hide conversation — drops it from the list (messages stay in the encrypted store; a
|
// Hide / Unhide. Hiding drops it from the list (messages stay in the encrypted store);
|
||||||
// new incoming message brings it back). Deselect so the thread resets to the next one.
|
// Unhide (shown only for a hidden conversation while "Show hidden" is on) restores it.
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton(TR("chat_hide")) && app->settings()) {
|
if (ImGui::SmallButton(sel->hidden ? TR("chat_unhide") : TR("chat_hide")) && app->settings()) {
|
||||||
app->markChatConversationSeen(sel->cid, sel->lastTs); // don't leave a phantom unread
|
if (sel->hidden) {
|
||||||
app->settings()->setChatHidden(sel->cid, true);
|
app->settings()->setChatHidden(sel->cid, false);
|
||||||
app->settings()->save();
|
app->settings()->save();
|
||||||
s_selected_cid.clear();
|
} else {
|
||||||
Notifications::instance().info(TR("chat_hidden_toast"));
|
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();
|
ImGui::Separator();
|
||||||
@@ -596,6 +696,13 @@ void RenderChatTab(App* app)
|
|||||||
if (material::TactileButton(TR("chat_send"), ImVec2(sendW, composerBoxH))) submit = true;
|
if (material::TactileButton(TR("chat_send"), ImVec2(sendW, composerBoxH))) submit = true;
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::PopStyleColor(3);
|
ImGui::PopStyleColor(3);
|
||||||
|
// Emoji picker button (left) + byte counter (right) on one row. The picker opens as an
|
||||||
|
// overlay over the conversation-list pane (rendered there), not a floating window.
|
||||||
|
ImGui::PushFont(nameFont); // Body2 has emoji merged, so the glyph renders
|
||||||
|
const bool emojiClicked = ImGui::SmallButton(u8"🙂");
|
||||||
|
ImGui::PopFont();
|
||||||
|
if (emojiClicked) { s_show_emoji_picker = !s_show_emoji_picker; s_emoji_search[0] = '\0'; }
|
||||||
|
ImGui::SameLine();
|
||||||
// Byte counter (Error tint over cap) with the over-cap label.
|
// Byte counter (Error tint over cap) with the over-cap label.
|
||||||
ImGui::PushFont(metaFont);
|
ImGui::PushFont(metaFont);
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, overCap ? material::Error() : material::OnSurfaceMedium());
|
ImGui::PushStyleColor(ImGuiCol_Text, overCap ? material::Error() : material::OnSurfaceMedium());
|
||||||
|
|||||||
@@ -253,6 +253,10 @@ void I18n::loadBuiltinEnglish()
|
|||||||
strings_["chat_mute"] = "Mute";
|
strings_["chat_mute"] = "Mute";
|
||||||
strings_["chat_unmute"] = "Unmute";
|
strings_["chat_unmute"] = "Unmute";
|
||||||
strings_["chat_hide"] = "Hide";
|
strings_["chat_hide"] = "Hide";
|
||||||
|
strings_["chat_unhide"] = "Unhide";
|
||||||
|
strings_["chat_show_hidden"] = "Show hidden";
|
||||||
|
strings_["chat_emoji_search"] = "Search emoji";
|
||||||
|
strings_["chat_hide_hidden"] = "Hide hidden";
|
||||||
strings_["chat_hidden_toast"] = "Conversation hidden — a new message brings it back";
|
strings_["chat_hidden_toast"] = "Conversation hidden — a new message brings it back";
|
||||||
strings_["chat_pick_contact"] = "Choose from contacts\xE2\x80\xA6";
|
strings_["chat_pick_contact"] = "Choose from contacts\xE2\x80\xA6";
|
||||||
strings_["chat_no_z_contacts"] = "No shielded-address contacts yet";
|
strings_["chat_no_z_contacts"] = "No shielded-address contacts yet";
|
||||||
|
|||||||
Reference in New Issue
Block a user