LCOV - code coverage report
Current view: top level - src/tui - history_pane.c (source / functions) Coverage Total Hit
Test: coverage-functional.info Lines: 94.2 % 52 49
Test Date: 2026-04-20 19:54:24 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-3.0-or-later */
       2              : /* Copyright 2026 Peter Csaszar */
       3              : 
       4              : /**
       5              :  * @file tui/history_pane.c
       6              :  * @brief Message history view-model implementation (US-11 v2).
       7              :  */
       8              : 
       9              : #include "tui/history_pane.h"
      10              : 
      11              : #include <stdio.h>
      12              : #include <string.h>
      13              : 
      14            3 : void history_pane_init(HistoryPane *hp) {
      15            3 :     if (!hp) return;
      16            3 :     memset(hp, 0, sizeof(*hp));
      17            3 :     list_view_init(&hp->lv);
      18              : }
      19              : 
      20            2 : void history_pane_set_entries(HistoryPane *hp,
      21              :                                const HistoryPeer *peer,
      22              :                                const HistoryEntry *src, int n) {
      23            2 :     if (!hp) return;
      24            2 :     if (n < 0) n = 0;
      25            2 :     if (n > HISTORY_PANE_MAX) n = HISTORY_PANE_MAX;
      26            2 :     if (src && n > 0) {
      27            2 :         memcpy(hp->entries, src, (size_t)n * sizeof(HistoryEntry));
      28              :     }
      29            2 :     hp->count = n;
      30            2 :     if (peer) hp->peer = *peer;
      31            2 :     hp->peer_loaded = 1;
      32            2 :     hp->lv.selected = (n > 0) ? 0 : -1;
      33            2 :     hp->lv.scroll_top = 0;
      34            2 :     list_view_set_count(&hp->lv, n);
      35              : }
      36              : 
      37            2 : int history_pane_load(HistoryPane *hp,
      38              :                        const ApiConfig *cfg,
      39              :                        MtProtoSession *s, Transport *t,
      40              :                        const HistoryPeer *peer) {
      41            2 :     if (!hp || !cfg || !s || !t || !peer) return -1;
      42            2 :     HistoryEntry tmp[HISTORY_PANE_MAX] = {0};
      43            2 :     int count = 0;
      44            2 :     if (domain_get_history(cfg, s, t, peer, 0,
      45              :                            HISTORY_PANE_MAX, tmp, &count) != 0) {
      46            0 :         return -1;
      47              :     }
      48            2 :     history_pane_set_entries(hp, peer, tmp, count);
      49            2 :     return 0;
      50              : }
      51              : 
      52              : /* Format one history row into a flat line. Returns bytes written
      53              :  * (excluding NUL). Examples:
      54              :  *     > [42] hello
      55              :  *     < [41] (media)
      56              :  *     < [40] (complex) */
      57            2 : static int format_row(const HistoryEntry *e, char *out, size_t cap) {
      58            2 :     char arrow = e->out ? '>' : '<';
      59              :     const char *body;
      60            2 :     if (e->complex)      body = "(complex)";
      61            2 :     else if (e->text[0]) body = e->text;
      62            0 :     else if (e->media)   body = "(media)";
      63            0 :     else                 body = "";
      64            2 :     return snprintf(out, cap, "%c [%d] %s", arrow, e->id, body);
      65              : }
      66              : 
      67            3 : void history_pane_render(const HistoryPane *hp,
      68              :                           const Pane *pane, Screen *screen) {
      69            3 :     if (!hp || !pane || !screen || !pane_is_valid(pane)) return;
      70            3 :     pane_clear(pane, screen);
      71              : 
      72            3 :     const char *placeholder = NULL;
      73            3 :     if (!hp->peer_loaded)  placeholder = "(select a dialog)";
      74            2 :     else if (hp->count==0) placeholder = "(no messages)";
      75              : 
      76            3 :     if (placeholder) {
      77            1 :         int mid_row = pane->rows / 2;
      78            1 :         int col = (pane->cols - (int)strlen(placeholder)) / 2;
      79            1 :         if (col < 0) col = 0;
      80            1 :         pane_put_str(pane, screen, mid_row, col,
      81              :                      placeholder, SCREEN_ATTR_DIM);
      82            1 :         return;
      83              :     }
      84              : 
      85            2 :     int first = hp->lv.scroll_top;
      86            2 :     int last  = first + hp->lv.rows_visible;
      87            2 :     if (last > hp->count) last = hp->count;
      88              : 
      89            4 :     for (int i = first; i < last; i++) {
      90            2 :         const HistoryEntry *e = &hp->entries[i];
      91              :         char line[HISTORY_TEXT_MAX + 32];
      92            2 :         format_row(e, line, sizeof(line));
      93            2 :         uint8_t attrs = 0;
      94            2 :         if (e->complex) attrs |= SCREEN_ATTR_DIM;
      95            2 :         pane_put_str(pane, screen, i - first, 0, line, attrs);
      96              :     }
      97              : }
        

Generated by: LCOV version 2.0-1