LCOV - code coverage report
Current view: top level - src/tui - history_pane.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.2 % 52 50
Test Date: 2026-04-20 19:54:22 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           34 : void history_pane_init(HistoryPane *hp) {
      15           34 :     if (!hp) return;
      16           34 :     memset(hp, 0, sizeof(*hp));
      17           34 :     list_view_init(&hp->lv);
      18              : }
      19              : 
      20           12 : void history_pane_set_entries(HistoryPane *hp,
      21              :                                const HistoryPeer *peer,
      22              :                                const HistoryEntry *src, int n) {
      23           12 :     if (!hp) return;
      24           12 :     if (n < 0) n = 0;
      25           12 :     if (n > HISTORY_PANE_MAX) n = HISTORY_PANE_MAX;
      26           12 :     if (src && n > 0) {
      27           10 :         memcpy(hp->entries, src, (size_t)n * sizeof(HistoryEntry));
      28              :     }
      29           12 :     hp->count = n;
      30           12 :     if (peer) hp->peer = *peer;
      31           12 :     hp->peer_loaded = 1;
      32           12 :     hp->lv.selected = (n > 0) ? 0 : -1;
      33           12 :     hp->lv.scroll_top = 0;
      34           12 :     list_view_set_count(&hp->lv, n);
      35              : }
      36              : 
      37            4 : int history_pane_load(HistoryPane *hp,
      38              :                        const ApiConfig *cfg,
      39              :                        MtProtoSession *s, Transport *t,
      40              :                        const HistoryPeer *peer) {
      41            4 :     if (!hp || !cfg || !s || !t || !peer) return -1;
      42            4 :     HistoryEntry tmp[HISTORY_PANE_MAX] = {0};
      43            4 :     int count = 0;
      44            4 :     if (domain_get_history(cfg, s, t, peer, 0,
      45              :                            HISTORY_PANE_MAX, tmp, &count) != 0) {
      46            0 :         return -1;
      47              :     }
      48            4 :     history_pane_set_entries(hp, peer, tmp, count);
      49            4 :     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           12 : static int format_row(const HistoryEntry *e, char *out, size_t cap) {
      58           12 :     char arrow = e->out ? '>' : '<';
      59              :     const char *body;
      60           12 :     if (e->complex)      body = "(complex)";
      61           10 :     else if (e->text[0]) body = e->text;
      62            1 :     else if (e->media)   body = "(media)";
      63            0 :     else                 body = "";
      64           12 :     return snprintf(out, cap, "%c [%d] %s", arrow, e->id, body);
      65              : }
      66              : 
      67           23 : void history_pane_render(const HistoryPane *hp,
      68              :                           const Pane *pane, Screen *screen) {
      69           23 :     if (!hp || !pane || !screen || !pane_is_valid(pane)) return;
      70           20 :     pane_clear(pane, screen);
      71              : 
      72           20 :     const char *placeholder = NULL;
      73           20 :     if (!hp->peer_loaded)  placeholder = "(select a dialog)";
      74            9 :     else if (hp->count==0) placeholder = "(no messages)";
      75              : 
      76           20 :     if (placeholder) {
      77           12 :         int mid_row = pane->rows / 2;
      78           12 :         int col = (pane->cols - (int)strlen(placeholder)) / 2;
      79           12 :         if (col < 0) col = 0;
      80           12 :         pane_put_str(pane, screen, mid_row, col,
      81              :                      placeholder, SCREEN_ATTR_DIM);
      82           12 :         return;
      83              :     }
      84              : 
      85            8 :     int first = hp->lv.scroll_top;
      86            8 :     int last  = first + hp->lv.rows_visible;
      87            8 :     if (last > hp->count) last = hp->count;
      88              : 
      89           20 :     for (int i = first; i < last; i++) {
      90           12 :         const HistoryEntry *e = &hp->entries[i];
      91              :         char line[HISTORY_TEXT_MAX + 32];
      92           12 :         format_row(e, line, sizeof(line));
      93           12 :         uint8_t attrs = 0;
      94           12 :         if (e->complex) attrs |= SCREEN_ATTR_DIM;
      95           12 :         pane_put_str(pane, screen, i - first, 0, line, attrs);
      96              :     }
      97              : }
        

Generated by: LCOV version 2.0-1