summaryrefslogtreecommitdiff
path: root/src/fruits/cmc/tui
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-10-21 19:22:50 -0400
committerAndrew Opalach <andrew@akon.city> 2024-10-21 19:22:50 -0400
commit60b4ebfbf3be78dba9dc7c65ab2bdaa0b218c0c2 (patch)
tree08ff2ce7975f523112e7ad2fe4f797b4fc7db5de /src/fruits/cmc/tui
parent2f9a0945bfeee3296cec3d38d094e4c49f9cb65f (diff)
downloadcamu-60b4ebfbf3be78dba9dc7c65ab2bdaa0b218c0c2.tar.gz
camu-60b4ebfbf3be78dba9dc7c65ab2bdaa0b218c0c2.tar.bz2
camu-60b4ebfbf3be78dba9dc7c65ab2bdaa0b218c0c2.zip
Everything before initial synced list
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/fruits/cmc/tui')
-rw-r--r--src/fruits/cmc/tui/pager.c88
-rw-r--r--src/fruits/cmc/tui/pager.h33
-rw-r--r--src/fruits/cmc/tui/pane_lists.c93
-rw-r--r--src/fruits/cmc/tui/pane_lists.h20
-rw-r--r--src/fruits/cmc/tui/pane_search.c335
-rw-r--r--src/fruits/cmc/tui/pane_search.h29
-rw-r--r--src/fruits/cmc/tui/resources.c85
-rw-r--r--src/fruits/cmc/tui/resources.h31
-rw-r--r--src/fruits/cmc/tui/ui.c144
-rw-r--r--src/fruits/cmc/tui/ui.h40
-rw-r--r--src/fruits/cmc/tui/view.h24
-rw-r--r--src/fruits/cmc/tui/view_twitter.c370
-rw-r--r--src/fruits/cmc/tui/view_twitter.h35
13 files changed, 0 insertions, 1327 deletions
diff --git a/src/fruits/cmc/tui/pager.c b/src/fruits/cmc/tui/pager.c
deleted file mode 100644
index a672315..0000000
--- a/src/fruits/cmc/tui/pager.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "pager.h"
-
-void cmc_pager_init(struct cmc_pager *pager, u32 page)
-{
- pager->find_anchor = PAGE_NONE;
- pager->anchor = 0;
- pager->redraw = true;
- pager->selected = 0;
- al_array_init(pager->prev);
- pager->max_page_num = page;
- pager->min_page_num = page;
- pager->end_of_page = -1;
- pager->pending_requests = 0;
- al_array_init(pager->pages);
-}
-
-static bool any_pending_requests(struct cmc_view_page *page)
-{
- struct cmc_view *view;
- al_array_foreach(page->views, j, view) {
- if (view->pending_requests > 0) {
- return true;
- }
- }
- return false;
-}
-
-bool cmc_pager_maybe_process_pages(struct cmc_pager *pager, void (*func)(void *, struct cmc_view_page *), void *userdata)
-{
- bool any_page_processed = false;
- struct cmc_view_page *page;
- al_array_foreach(pager->pages, i, page) {
- if (page->processed) continue;
- if (!any_pending_requests(page)) {
- page->processed = true;
- func(userdata, page);
- any_page_processed = true;
- }
- }
- return any_page_processed;
-}
-
-struct cmc_view_page *cmc_get_page_from_num(struct cmc_pager *pager, u32 num)
-{
- struct cmc_view_page *page;
- al_array_foreach(pager->pages, i, page) {
- if (page->num == num) return page;
- }
- return NULL;
-}
-
-struct cmc_view_page *cmc_pager_page_containing_index(struct cmc_pager *pager, u32 index, u32 *offset)
-{
- u32 count = 0, size = 0;
- struct cmc_view_page *page = NULL;
- for (u32 i = pager->min_page_num; i <= pager->max_page_num; i++) {
- if (!(page = cmc_get_page_from_num(pager, i))) continue;
- size = page->views.size;
- count += size;
- if (count > index) {
- if (offset) *offset = size - (count - index);
- return page;
- }
- }
- return NULL;
-}
-
-bool cmc_pager_iterate_to_height(struct cmc_pager *pager, u32 height, u32 anchor, u32 *count,
- void (*func)(void *, struct cmc_view *, u32), void *userdata)
-{
- u32 y = 0, offset;
- struct cmc_view_page *page = cmc_pager_page_containing_index(pager, anchor, &offset);
- if (!page) return false;
- struct cmc_view *view;
- do {
- // If the page is not processed, return out of space as to not display a discontinuity.
- if (!page->processed) return true;
- for (; offset < page->views.size; offset++) {
- view = al_array_at(page->views, offset);
- // If this post would draw past the height, return out of space.
- if (y + view->rows > height) return true;
- if (func) func(userdata, view, y);
- (*count)++;
- y += view->rows + 1;
- }
- } while ((offset = 0, (page = cmc_get_page_from_num(pager, page->num + 1))));
- return false;
-}
diff --git a/src/fruits/cmc/tui/pager.h b/src/fruits/cmc/tui/pager.h
deleted file mode 100644
index 6aeeb9c..0000000
--- a/src/fruits/cmc/tui/pager.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <al/types.h>
-#include <al/array.h>
-
-#include "view.h"
-
-enum {
- PAGE_NONE = 0,
- PAGE_UP,
- PAGE_DOWN
-};
-
-struct cmc_pager {
- u8 find_anchor;
- s32 anchor;
- bool redraw;
- u32 count;
- s32 selected;
- array(struct cmc_view *) prev;
- u32 max_page_num;
- u32 min_page_num;
- s32 end_of_page;
- u32 pending_requests;
- array(struct cmc_view_page *) pages;
-};
-
-void cmc_pager_init(struct cmc_pager *pager, u32 page);
-bool cmc_pager_maybe_process_pages(struct cmc_pager *pager, void (*func)(void *, struct cmc_view_page *), void *userdata);
-struct cmc_view_page *cmc_get_page_from_num(struct cmc_pager *pager, u32 num);
-struct cmc_view_page *cmc_pager_page_containing_index(struct cmc_pager *pager, u32 index, u32 *offset);
-bool cmc_pager_iterate_to_height(struct cmc_pager *pager, u32 height, u32 anchor, u32 *count,
- void (*func)(void *, struct cmc_view *, u32), void *userdata);
diff --git a/src/fruits/cmc/tui/pane_lists.c b/src/fruits/cmc/tui/pane_lists.c
deleted file mode 100644
index 6367e57..0000000
--- a/src/fruits/cmc/tui/pane_lists.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "../cmc.h"
-
-#include "pane_lists.h"
-#include "ui.h"
-
-void cmc_pane_lists_init(struct cmc_pane_lists *pane, struct cmc_ui *ui)
-{
- pane->offset = 0;
- pane->selected = 0;
- pane->list = al_array_at(ui->c->client.state.lists, 0);
- pane->ui = ui;
-}
-
-bool cmc_pane_lists_handle_input(struct cmc_pane_lists *pane, struct ncinput *input)
-{
- if (!(input->evtype == NCTYPE_PRESS || input->evtype == NCTYPE_UNKNOWN)) return false;
- s32 rows = pane->ui->rows - 1;
- s32 size = (s32)pane->list->entries.size;
- if (input->id == 'j') {
- if (pane->selected + 1 < size) {
- pane->selected++;
- if (pane->selected - pane->offset >= rows) {
- pane->offset += rows;
- }
- return true;
- }
- } else if (input->id == 'k') {
- if (pane->selected - 1 >= 0) {
- pane->selected--;
- if (pane->selected - pane->offset < 0) {
- pane->offset -= rows;
- }
- return true;
- }
- } else if (input->id == 'n') {
- if (pane->offset + rows < size) {
- pane->offset += rows;
- pane->selected += rows;
- if (pane->selected >= size) {
- pane->selected = size - 1;
- }
- return true;
- }
- } else if (input->id == 'p') {
- if (pane->offset - rows >= 0) {
- pane->offset -= rows;
- pane->selected -= rows;
- return true;
- }
- } else if (input->id == NCKEY_RETURN) {
- camu_client_skipto(&pane->ui->c->client, pane->selected);
- }
- return false;
-}
-
-bool cmc_pane_lists_handle_input_overlay(struct cmc_pane_lists *pane, struct ncinput *input)
-{
- (void)pane;
- (void)input;
- return false;
-}
-
-void cmc_pane_lists_draw_overlay(struct cmc_pane_lists *pane)
-{
- (void)pane;
-}
-
-void cmc_pane_lists_refresh(struct cmc_pane_lists *pane)
-{
- struct cmc_ui *ui = pane->ui;
-
- ncplane_cursor_move_yx(ui->p, 0, 0);
- ncplane_erase(ui->p);
- notcurses_refresh(ui->nc, NULL, NULL);
- notcurses_render(ui->nc);
-
- str *unique_id;
- u32 rows = AL_MIN(pane->list->entries.size - pane->offset, ui->rows - 1);
- for (u32 i = pane->offset; i < pane->offset + rows; i++) {
- unique_id = &al_array_at(pane->list->entries, i);
- if ((s32)i == pane->selected) {
- ncplane_set_fg_palindex(ui->p, 4);
- } else {
- ncplane_set_fg_default(ui->p);
- }
- u32 cols = AL_MIN(unique_id->len, ui->cols);
- for (u32 j = 0; j < cols; j++) {
- ncplane_putchar_yx(ui->p, i - pane->offset, j + 1, al_str_at(unique_id, j));
- }
- }
-
- notcurses_render(ui->nc);
-}
diff --git a/src/fruits/cmc/tui/pane_lists.h b/src/fruits/cmc/tui/pane_lists.h
deleted file mode 100644
index 323eb52..0000000
--- a/src/fruits/cmc/tui/pane_lists.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <al/types.h>
-#include <notcurses/notcurses.h>
-
-#include "../../libclient/client.h"
-
-struct cmc_ui;
-struct cmc_pane_lists {
- s32 offset;
- s32 selected;
- struct camu_list *list;
- struct cmc_ui *ui;
-};
-
-void cmc_pane_lists_init(struct cmc_pane_lists *pane, struct cmc_ui *ui);
-bool cmc_pane_lists_handle_input(struct cmc_pane_lists *pane, struct ncinput *input);
-bool cmc_pane_lists_handle_input_overlay(struct cmc_pane_lists *pane, struct ncinput *input);
-void cmc_pane_lists_draw_overlay(struct cmc_pane_lists *pane);
-void cmc_pane_lists_refresh(struct cmc_pane_lists *pane);
diff --git a/src/fruits/cmc/tui/pane_search.c b/src/fruits/cmc/tui/pane_search.c
deleted file mode 100644
index 002a4d1..0000000
--- a/src/fruits/cmc/tui/pane_search.c
+++ /dev/null
@@ -1,335 +0,0 @@
-#include <al/lib.h>
-#include <notcurses/nckeys.h>
-
-#include "../cmc.h"
-
-#include "pane_search.h"
-#include "view_twitter.h"
-#include "ui.h"
-
-static void request_page_internal(struct cmc *c, struct cmc_search *search, u32 num)
-{
- search->pager.pending_requests++;
- camu_client_get_page(&c->client, search->search, num);
-}
-
-void cmc_pane_search_init(struct cmc_pane_search *pane, struct cmc_ui *ui)
-{
- pane->ui = ui;
- al_array_init(pane->searches);
- pane->search = NULL;
- struct camu_search *s;
- al_array_foreach(pane->ui->c->client.state.searches, i, s) {
- struct cmc_search *search = al_alloc_object(struct cmc_search);
- search->search = s;
- cmc_pager_init(&search->pager, s->page);
- al_array_push(pane->searches, search);
- }
- if (pane->searches.size > 0) {
- pane->search = al_array_at(pane->searches, 0);
- }
-}
-
-static struct cmc_view *get_view_by_visual_index(struct cmc_pager *pager, s32 index)
-{
- u32 offset;
- struct cmc_view_page *page = cmc_pager_page_containing_index(pager, pager->anchor + index, &offset);
- if (!page || !page->processed) return NULL;
- return al_array_at(page->views, offset);
-}
-
-// Given an index of a post, request the page to the offset of the page containing that post.
-static bool request_page_at_page_offset(struct cmc_pane_search *pane, struct cmc_pager *pager, u32 index, s32 offset)
-{
- struct cmc_view_page *page = cmc_pager_page_containing_index(pager, index, NULL);
- if (page) {
- s32 req = (s32)page->num + offset;
- if (req < 0) return false;
- request_page_internal(pane->ui->c, pane->search, req);
- }
- return true;
-}
-
-static void add_selected_from_index(struct cmc *c, struct cmc_pager *pager, u32 index)
-{
- struct cmc_view *view = get_view_by_visual_index(pager, pager->selected);
- if (view && view->post->media.size > index) {
- camu_client_add(&c->client, &view->post->unique_id, index, true);
- }
-}
-
-#define ON_LAST_PAGE(pager) \
- (pager->end_of_page >= 0 && pager->anchor + pager->count > (u32)pager->end_of_page)
-
-bool cmc_pane_search_handle_input(struct cmc_pane_search *pane, struct ncinput *input)
-{
- struct cmc_pager *pager = &pane->search->pager;
- if (!(input->evtype == NCTYPE_PRESS || input->evtype == NCTYPE_UNKNOWN)) return false;
- if (input->id == 'j') {
- if (pager->selected + 1 >= (s32)pager->count) {
- if (pager->pending_requests > 0 || pager->find_anchor != PAGE_NONE) return false;
- if (ON_LAST_PAGE(pager)) return false;
- if (pager->count == 0) pager->count = 1;
- u32 index = pager->anchor + pager->count;
- pager->find_anchor = PAGE_DOWN;
- struct cmc_view_page *page = cmc_pager_page_containing_index(pager, index, NULL);
- if (!page) {
- request_page_at_page_offset(pane, pager, index - 1, 1);
- return false;
- }
- } else {
- pager->selected++;
- }
- return true;
- } else if (input->id == 'k') {
- if (pager->selected - 1 < 0) {
- if (pager->pending_requests > 0 || pager->find_anchor != PAGE_NONE) return false;
- if (pager->anchor - 1 < 0 && !request_page_at_page_offset(pane, pager, 0, -1)) {
- // The reason to do this here instead of letting it resolve in
- // refresh_pane_pager() is so we can return early if
- // we are at the top of the page.
- return false;
- }
- pager->anchor--;
- pager->find_anchor = PAGE_UP;
- // Wait for the requested previous page to come in.
- if (pager->anchor < 0) return false;
- } else {
- pager->selected--;
- }
- return true;
- } else if (input->id == NCKEY_RETURN || input->id == '1') {
- add_selected_from_index(pane->ui->c, pager, 0);
- } else if (input->id == '2') {
- add_selected_from_index(pane->ui->c, pager, 1);
- } else if (input->id == '3') {
- add_selected_from_index(pane->ui->c, pager, 2);
- } else if (input->id == '4') {
- add_selected_from_index(pane->ui->c, pager, 3);
- }
- return false;
-}
-
-bool cmc_pane_search_handle_input_overlay(struct cmc_pane_search *pane, struct ncinput *input)
-{
- if (!(input->evtype == NCTYPE_PRESS || input->evtype == NCTYPE_UNKNOWN)) return false;
- struct cmc_ui *ui = pane->ui;
- struct cmc_pager *pager = &pane->search->pager;
- if (input->id == NCKEY_TAB) {
- pager->redraw = true;
- } else if (input->id == 'j') {
- if (ui->overlay.selected + 1 < (s32)pane->searches.size) {
- ui->overlay.selected++;
- return true;
- }
- } else if (input->id == 'k') {
- if (ui->overlay.selected - 1 >= 0) {
- ui->overlay.selected--;
- return true;
- }
- } else if (input->id == NCKEY_RETURN) {
- cmc_ui_toggle_overlay(ui);
- struct cmc_view *view;
- al_array_foreach(pager->prev, j, view) {
- ncplane_erase(view->container);
- ncplane_reparent_family(view->container, view->container);
- }
- pager->prev.size = 0;
- pane->search = al_array_at(pane->searches, ui->overlay.selected);
- pager = &pane->search->pager;
- pager->redraw = true;
- return true;
- }
- return false;
-}
-
-void cmc_pane_search_maybe_draw_overlay(struct cmc_pane_search *pane)
-{
- struct cmc_ui *ui = pane->ui;
-
- if (!ui->overlay.active) return;
-
- ncplane_cursor_move_yx(ui->overlay.p, 0, 0);
- ncplane_erase(ui->overlay.p);
-
- u64 color = 0;
- u32 background = 0;
- ncchannel_set_rgb8(&background, 255, 255, 255);
- ncchannel_set_alpha(&background, 255);
- ncchannels_set_fchannel(&color, background);
-
- ncchannel_set_rgb8(&background, 124, 12, 53);
- ncchannels_set_bchannel(&color, background);
- ncchannels_set_fchannel(&color, background);
- ncplane_gradient(ui->overlay.p, 0, 0, ui->overlay.rows, ui->overlay.cols, "", 0, color, color, color, color);
-
- ncplane_set_bg_rgb8(ui->overlay.p, 124, 12, 53);
-
- struct cmc_search *search;
- al_array_foreach(ui->search.searches, i, search) {
- if ((s32)i == ui->overlay.selected) {
- ncplane_set_fg_palindex(ui->overlay.p, 4);
- } else {
- ncplane_set_fg_default(ui->overlay.p);
- }
- str *query = &search->search->query;
- for (u32 j = 0; j < query->len; j++) {
- ncplane_putchar_yx(ui->overlay.p, i, j + 1, al_str_at(query, j));
- }
- }
-}
-
-static void draw_selection_line(struct cmc_view *view, u32 y, u32 rows)
-{
- ncplane_move_yx(view->container, y, 0);
- wchar_t box = L'█';
- u32 k = ((struct cmc_view_twitter *)view)->repost ? 1 : 0;
- for (; k < rows - 1; k++) {
- ncplane_cursor_move_yx(view->container, k, 0);
- ncplane_putwc(view->container, box);
- }
-}
-
-void cmc_pane_search_refresh(struct cmc_pane_search *pane)
-{
- struct cmc_pager *pager = &pane->search->pager;
- if (pager->pending_requests > 0) return;
-
- u32 page = pane->search->search->page;
- if (!cmc_get_page_from_num(pager, page)) {
- request_page_internal(pane->ui->c, pane->search, page);
- return;
- }
-
- if (pager->find_anchor == PAGE_UP) {
- u32 count;
- // If find_anchor = PAGE_UP, search->anchor is index of the requested view.
- s32 anchor = pager->anchor;
- while (anchor >= 0) {
- count = 0;
- cmc_pager_iterate_to_height(pager, pane->ui->rows, anchor, &count, NULL, NULL);
- // TODO: Handle count == 0.
- // Is the requested view still visible?
- if ((s32)(anchor + count) - 1 < pager->anchor) break;
- anchor--;
- // Load more posts if needed.
- if (anchor < 0 && request_page_at_page_offset(pane, pager, 0, -1)) return;
- }
- anchor++; // We want the anchor before the last attempt above.
- pager->selected = abs(pager->anchor - anchor);
- pager->anchor = anchor;
- pager->redraw = true;
- pager->find_anchor = PAGE_NONE;
- } else if (pager->find_anchor == PAGE_DOWN) {
- // When moving down we already know how many views are being displayed
- // so just move the anchor 1 past that.
- pager->selected = 0;
- pager->anchor += pager->count;
- pager->redraw = true;
- pager->find_anchor = PAGE_NONE;
- }
-
- cmc_pane_search_maybe_draw_overlay(pane);
-
- struct cmc_view *view;
- bool out_of_space = true;
- if (pager->redraw) {
- al_array_foreach(pager->prev, j, view) {
- ncplane_erase(view->container);
- ncplane_reparent_family(view->container, view->container);
- }
- pager->prev.size = 0;
- pager->count = 0;
- out_of_space = cmc_pager_iterate_to_height(pager, pane->ui->rows, pager->anchor, &pager->count, cmc_draw_tweet_func, pane->ui);
- } else {
- al_array_foreach(pager->prev, j, view) {
- ncplane_erase(view->container);
- }
- }
- if ((view = get_view_by_visual_index(pager, pager->selected))) {
- draw_selection_line(view, view->y, view->rows);
- }
- if (pager->redraw) {
- pager->redraw = false;
- notcurses_refresh(pane->ui->nc, NULL, NULL);
- }
- notcurses_render(pane->ui->nc);
- if (pager->count > 0 && !out_of_space && pager->end_of_page == -1) {
- request_page_at_page_offset(pane, pager, (pager->anchor + pager->count) - 1, 1);
- }
-}
-
-static struct cmc_search *get_search_from_id(struct cmc_pane_search *pane, s32 id)
-{
- struct cmc_search *search;
- al_array_foreach(pane->searches, i, search) {
- if (search->search->id == id) return search;
- }
- return NULL;
-}
-
-static void process_page_func(void *userdata, struct cmc_view_page *page)
-{
- struct cmc_ui *ui = (struct cmc_ui *)userdata;
- struct cmc_view *view;
- al_array_foreach(page->views, i, view) {
- view->rows = cmc_layout_tweet(ui, (struct cmc_view_twitter *)view, ui->cols);
- cmc_draw_tweet((struct cmc_view_twitter *)view, view->container, view->rows, ui->cols);
- }
-}
-
-void cmc_ui_resources_callback(void *userdata)
-{
- struct cmc_pane_search *pane = (struct cmc_pane_search *)userdata;
- struct cmc_pager *pager = &pane->search->pager;
- if (cmc_pager_maybe_process_pages(pager, process_page_func, pane->ui)) {
- pager->redraw = true;
- cmc_pane_search_refresh(pane);
- }
-}
-
-void cmc_ui_handle_results(struct cmc_pane_search *pane, struct camu_result_list *results)
-{
- struct cmc_search *search = get_search_from_id(pane, results->search->id);
- if (!search) return;
- struct cmc_pager *pager = &search->pager;
- pager->pending_requests--;
-
- struct cmc_view_page *page = al_alloc_object(struct cmc_view_page);
- al_array_push(pager->pages, page);
- page->num = results->num;
- page->processed = false;
- if (page->num > pager->max_page_num) pager->max_page_num = page->num;
- if (page->num < pager->min_page_num) pager->min_page_num = page->num;
- if (pager->find_anchor == PAGE_UP) {
- pager->anchor += results->unique_ids.size;
- if (pager->end_of_page >= 0) {
- pager->end_of_page += results->unique_ids.size;
- }
- }
-
- str *unique_id;
- struct cmc_view_twitter *view;
- al_array_foreach_ptr(results->unique_ids, i, unique_id) {
- view = cmc_create_view_twitter(pane->ui, unique_id);
- al_array_push(page->views, &view->v);
- }
-
- if (cmc_pager_maybe_process_pages(pager, process_page_func, pane->ui)) {
- pager->redraw = true;
- cmc_pane_search_refresh(pane);
- }
-}
-
-void cmc_ui_handle_end_of_results(struct cmc_pane_search *pane, s32 id)
-{
- struct cmc_search *search = get_search_from_id(pane, id);
- if (!search) return;
- struct cmc_pager *pager = &search->pager;
- pager->pending_requests--;
- pager->end_of_page = (pager->anchor + pager->count) - 1;
- if (cmc_pager_maybe_process_pages(pager, process_page_func, pane->ui)) {
- pager->redraw = true;
- cmc_pane_search_refresh(pane);
- }
-}
diff --git a/src/fruits/cmc/tui/pane_search.h b/src/fruits/cmc/tui/pane_search.h
deleted file mode 100644
index b7c5e2c..0000000
--- a/src/fruits/cmc/tui/pane_search.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <notcurses/notcurses.h>
-
-#include "../../libclient/client.h"
-
-#include "pager.h"
-
-struct cmc_search {
- struct camu_search *search;
- struct cmc_pager pager;
-};
-
-struct cmc_ui;
-struct cmc_pane_search {
- array(struct cmc_search *) searches;
- struct cmc_search *search;
- struct cmc_ui *ui;
-};
-
-void cmc_pane_search_init(struct cmc_pane_search *pane, struct cmc_ui *ui);
-bool cmc_pane_search_handle_input(struct cmc_pane_search *pane, struct ncinput *input);
-bool cmc_pane_search_handle_input_overlay(struct cmc_pane_search *pane, struct ncinput *input);
-void cmc_pane_search_draw_overlay(struct cmc_pane_search *pane);
-void cmc_pane_search_refresh(struct cmc_pane_search *pane);
-
-void cmc_ui_resources_callback(void *userdata);
-void cmc_ui_handle_results(struct cmc_pane_search *pane, struct camu_result_list *results);
-void cmc_ui_handle_end_of_results(struct cmc_pane_search *pane, s32 id);
diff --git a/src/fruits/cmc/tui/resources.c b/src/fruits/cmc/tui/resources.c
deleted file mode 100644
index 19513bf..0000000
--- a/src/fruits/cmc/tui/resources.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <al/log.h>
-#include <al/random.h>
-#define STB_IMAGE_IMPLEMENTATION
-#define STB_IMAGE_STATIC
-#define STBI_NO_STDIO
-#define STBI_NO_FAILURE_STRINGS
-#define STBI_MALLOC al_malloc
-#define STBI_FREE al_free
-#define STBI_REALLOC al_realloc
-#include <stb_image.h>
-
-#include "resources.h"
-#include "view.h"
-
-static void resource_client_callback(void *userdata, u16 id, struct aki_buffer *buffer)
-{
- struct cmc_resources *resources = (struct cmc_resources *)userdata;
- struct cmc_view_resource *resource;
- al_array_foreach(resources->cache, i, resource) {
- if (resource->id == id) {
- s32 w, h, channels;
- u8 *pixels = stbi_load_from_memory(aki_buffer_get_ptr(buffer, 0), buffer->size, &w, &h, &channels, 0);
- if (channels == 3) {
- resource->v = ncvisual_from_rgb_packed(pixels, h, w * channels, w, 255);
- } else if (channels == 4) {
- resource->v = ncvisual_from_rgba(pixels, h, w * channels, w);
- } else {
- al_log_warn("cmc", "Image has unsupported channel count.");
- }
- stbi_image_free(pixels);
- ncvisual_geom(resources->nc, resource->v, &resource->vopts, &resource->geom);
- struct cmc_view *view;
- al_array_foreach(resource->refs, j, view) {
- view->pending_requests--;
- }
- al_array_free(resource->refs);
- break;
- }
- }
- resources->callback(resources->userdata);
-}
-
-bool cmc_resources_connect(struct cmc_resources *resources, struct notcurses *nc,
- struct aki_event_loop *loop, str *addr, s32 port)
-{
- resources->nc = nc;
- resources->pending_requests = 0;
- camu_resource_client_init(&resources->client, loop, resource_client_callback, resources);
- return camu_resource_client_connect(&resources->client, addr, port);
-}
-
-void cmc_resources_set_callback(struct cmc_resources *resources, void (*callback)(void *), void *userdata)
-{
- resources->callback = callback;
- resources->userdata = userdata;
-}
-
-static struct cmc_view_resource *create_resource(struct cmc_resources *resources, str *unique_id, u32 index)
-{
- struct cmc_view_resource *resource = al_alloc_object(struct cmc_view_resource);
- al_array_push(resources->cache, resource);
- resource->vopts.blitter = NCBLIT_PIXEL;
- resource->vopts.scaling = NCSCALE_SCALE;
- resource->id = al_rand_u16();
- al_str_clone(&resource->unique_id, unique_id);
- resource->index = index;
- al_array_init(resource->refs);
- camu_resource_request(&resources->client, unique_id, index, resource->id);
- return resource;
-}
-
-struct cmc_view_resource *cmc_get_resource_from_cache(struct cmc_resources *resources, struct cmc_view *view,
- str *unique_id, u32 index)
-{
- struct cmc_view_resource *resource;
- al_array_foreach(resources->cache, i, resource) {
- if (al_str_eq(&resource->unique_id, unique_id) && resource->index == index) {
- return resource;
- }
- }
- resource = create_resource(resources, unique_id, index);
- view->pending_requests++;
- al_array_push(resource->refs, view);
- return resource;
-}
diff --git a/src/fruits/cmc/tui/resources.h b/src/fruits/cmc/tui/resources.h
deleted file mode 100644
index f12d861..0000000
--- a/src/fruits/cmc/tui/resources.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <notcurses/notcurses.h>
-
-#include "../../libclient/resource_client.h"
-
-struct cmc_view;
-struct cmc_view_resource {
- u16 id;
- str unique_id;
- u32 index;
- array(struct cmc_view *) refs;
- struct ncvisual *v;
- struct ncvgeom geom;
- struct ncvisual_options vopts;
-};
-
-struct cmc_resources {
- struct camu_resource_client client;
- u32 pending_requests;
- struct notcurses *nc;
- array(struct cmc_view_resource *) cache;
- void (*callback)(void *);
- void *userdata;
-};
-
-bool cmc_resources_connect(struct cmc_resources *resources, struct notcurses *nc,
- struct aki_event_loop *loop, str *addr, s32 port);
-void cmc_resources_set_callback(struct cmc_resources *resources, void (*callback)(void *), void *userdata);
-struct cmc_view_resource *cmc_get_resource_from_cache(struct cmc_resources *resources, struct cmc_view *view,
- str *unique_id, u32 index);
diff --git a/src/fruits/cmc/tui/ui.c b/src/fruits/cmc/tui/ui.c
deleted file mode 100644
index 2c406bd..0000000
--- a/src/fruits/cmc/tui/ui.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "../../server/common.h"
-
-#include "../cmc.h"
-
-#include "ui.h"
-
-/*
-struct nccell ul, ur; nccell_init(&ul); nccell_init(&ur);
-struct nccell ll, lr; nccell_init(&ll); nccell_init(&lr);
-struct nccell hl, vl; nccell_init(&hl); nccell_init(&vl);
-//nccell_set_channels(&hl, color);
-//nccell_set_channels(&vl, color);
-
-ncplane_box(tui->overlay.p, &ul, &ur, &ll, &lr, &hl, &vl, tui->overlay.rows - 1, tui->overlay.cols - 1, 0);
-
-nccell_release(tui->overlay.p, &ul); nccell_release(tui->overlay.p, &ur);
-nccell_release(tui->overlay.p, &ll); nccell_release(tui->overlay.p, &lr);
-nccell_release(tui->overlay.p, &hl); nccell_release(tui->overlay.p, &vl);
-*/
-
-//ncplane_double_box(tui->overlay.p, NCSTYLE_NONE, color, tui->overlay.rows - 1, tui->overlay.cols - 1, 0);
-//ncplane_rounded_box(tui->overlay.p, NCSTYLE_NONE, color, tui->overlay.rows - 1, tui->overlay.cols - 1, 0);
-
-void cmc_ui_toggle_overlay(struct cmc_ui *ui)
-{
- if (ui->overlay.active) {
- ncplane_reparent_family(ui->overlay.p, ui->overlay.p);
- } else {
- ncplane_reparent_family(ui->overlay.p, ui->p);
- }
- ui->overlay.active = !ui->overlay.active;
-}
-
-static void refresh_internal(struct cmc_ui *ui)
-{
- switch (ui->pane) {
- case CMC_PANE_LIBRARY:
- break;
- case CMC_PANE_LISTS:
- cmc_pane_lists_refresh(&ui->lists);
- break;
- case CMC_PANE_BROWSE:
- break;
- case CMC_PANE_SEARCH:
- cmc_pane_search_refresh(&ui->search);
- break;
- }
-}
-
-static void input_poll_callback(void *userdata, s32 revents)
-{
- struct cmc_ui *ui = (struct cmc_ui *)userdata;
- (void)revents;
- struct ncinput input;
- u32 ret;
- bool do_refresh = false;
- do {
- ret = notcurses_get_nblock(ui->nc, &input);
- if (ret == (u32)-1 || ret == 0) break;
- if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
- if (input.id == 'q') {
- aki_event_loop_break(&ui->c->loop);
- break;
- } else if (input.id == NCKEY_TAB) {
- cmc_ui_toggle_overlay(ui);
- do_refresh = true;
- }
- switch (ui->pane) {
- case CMC_PANE_LIBRARY:
- break;
- case CMC_PANE_LISTS:
- if (ui->overlay.active) {
- do_refresh |= cmc_pane_lists_handle_input_overlay(&ui->lists, &input);
- } else {
- do_refresh |= cmc_pane_lists_handle_input(&ui->lists, &input);
- }
- break;
- case CMC_PANE_BROWSE:
- break;
- case CMC_PANE_SEARCH:
- if (ui->overlay.active) {
- do_refresh |= cmc_pane_search_handle_input_overlay(&ui->search, &input);
- } else {
- do_refresh |= cmc_pane_search_handle_input(&ui->search, &input);
- }
- break;
- }
- }
- } while (1);
- if (do_refresh) refresh_internal(ui);
-}
-
-static s32 resize_cb(struct ncplane *p)
-{
- struct cmc_ui *ui = (struct cmc_ui *)ncplane_userptr(p);
- notcurses_stddim_yx(ui->nc, &ui->rows, &ui->cols);
- ui->cols -= 4;
- ui->rows -= 1;
- struct ncplane_options nopts = { 0 };
- nopts.cols = ui->cols;
- nopts.rows = ui->rows;
- nopts.x = 3;
- nopts.y = 1;
- nopts.flags = 0;
- ui->p = ncplane_create(p, &nopts);
- ui->pane = CMC_PANE_SEARCH;
- ui->overlay.cols = nopts.cols = 35;
- ui->overlay.rows = nopts.rows = 20;
- nopts.x = (ui->cols / 2) - (ui->overlay.cols / 2);
- nopts.y = (ui->rows / 2) - (ui->overlay.rows / 2);
- ui->overlay.p = ncpile_create(ui->nc, &nopts);
- return 0;
-}
-
-bool cmc_ui_open(struct cmc_ui *ui, struct cmc *c)
-{
- if (!(ui->nc = notcurses_init(NULL, stdin))) return false;
-
- ui->c = c;
-
- cmc_pane_lists_init(&ui->lists, ui);
- cmc_pane_search_init(&ui->search, ui);
-
- //if (!cmc_resources_connect(&ui->resources, ui->nc, &ui->c->loop, CAMU_SERVER_IP, CAMU_RESOURCE_PORT)) {
- // return false;
- //}
- cmc_resources_set_callback(&ui->resources, cmc_ui_resources_callback, &ui->search);
-
- aki_poll_init(&ui->input, input_poll_callback, ui);
- aki_poll_set(&ui->input, notcurses_inputready_fd(ui->nc), AKI_POLL_READ);
- aki_poll_start(&ui->input, &c->loop);
-
- ui->overlay.active = false;
- ui->overlay.selected = 0;
-
- struct ncplane *stdplane = notcurses_stdplane(ui->nc);
- ncplane_set_resizecb(stdplane, resize_cb);
- ncplane_set_userptr(stdplane, ui);
- resize_cb(stdplane);
-
- refresh_internal(ui);
-
- return true;
-}
diff --git a/src/fruits/cmc/tui/ui.h b/src/fruits/cmc/tui/ui.h
deleted file mode 100644
index 76ea353..0000000
--- a/src/fruits/cmc/tui/ui.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <aki/event_loop.h>
-#include <notcurses/notcurses.h>
-
-#include "resources.h"
-#include "pane_lists.h"
-#include "pane_search.h"
-
-enum {
- CMC_PANE_LIBRARY = 0,
- CMC_PANE_LISTS,
- CMC_PANE_BROWSE,
- CMC_PANE_SEARCH
-};
-
-struct cmc;
-struct cmc_ui {
- struct notcurses *nc;
- u32 cols;
- u32 rows;
- struct ncplane *p;
- u8 pane;
- struct {
- struct ncplane *p;
- u32 cols;
- u32 rows;
- bool active;
- s32 selected;
- } overlay;
- struct aki_poll input;
- struct cmc_resources resources;
- struct cmc_pane_lists lists;
- struct cmc_pane_search search;
- struct cmc *c;
-};
-
-bool cmc_ui_open(struct cmc_ui *ui, struct cmc *c);
-void cmc_ui_toggle_overlay(struct cmc_ui *ui);
-void cmc_ui_maybe_draw_overlay(struct cmc_ui *ui);
diff --git a/src/fruits/cmc/tui/view.h b/src/fruits/cmc/tui/view.h
deleted file mode 100644
index 3c521c3..0000000
--- a/src/fruits/cmc/tui/view.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <al/types.h>
-#include <sho/post.h>
-
-enum {
- CMC_VIEW_NONE = 0,
- CMC_VIEW_SINGLE,
- CMC_VIEW_PARTITION
-};
-
-struct cmc_view {
- struct sho_post *post;
- struct ncplane *container;
- u32 pending_requests;
- u32 rows;
- u32 y;
-};
-
-struct cmc_view_page {
- u32 num;
- bool processed;
- array(struct cmc_view *) views;
-};
diff --git a/src/fruits/cmc/tui/view_twitter.c b/src/fruits/cmc/tui/view_twitter.c
deleted file mode 100644
index b1070a4..0000000
--- a/src/fruits/cmc/tui/view_twitter.c
+++ /dev/null
@@ -1,370 +0,0 @@
-#include "../cmc.h"
-
-#include "view_twitter.h"
-
-#define TEXT_OFFSET 10
-
-#define PROFILE_SIZE 5
-#define PREVIEW_OFFSET_WIDTH 26
-
-static u32 count_wrapped_lines(wstr *w, u32 width)
-{
- u32 counter = 0, wraps = 1;
- for (u32 i = 0; i < w->len; i++) {
- wchar_t wc = al_wstr_at(w, i);
- s32 wcwidth = al_wchar_width(wc);
- bool newline = wc == L'\n';
- if (newline || counter + wcwidth > width) {
- wraps++;
- counter = 0;
- }
- if (newline) continue;
- counter += wcwidth;
- }
- return wraps;
-}
-
-u32 cmc_layout_tweet(struct cmc_ui *ui, struct cmc_view_twitter *view, u32 width)
-{
- struct sho_post *post = view->v.post;
- struct sho_post *repost = view->repost;
-
- u32 rows = 1;
-
- view->text.width = width - TEXT_OFFSET;
- view->text.height = 1 + count_wrapped_lines(&post->text, view->text.width);
- view->text.y = repost ? 1 : 0;
- view->text.height += view->text.y;
- rows += view->text.height;
-
- if (view->preview.mode == CMC_VIEW_NONE) {
- return rows;
- }
-
- view->preview.width = view->text.width - 1;
- view->preview.x = TEXT_OFFSET;
- u32 partition_width = view->preview.width / 2;
-
- struct ncplane_options opts = { 0 };
- opts.cols = view->preview.width;
- opts.rows = ncplane_dim_y(notcurses_stdplane(ui->nc)) / 3;
- opts.x = 0;
- opts.y = 0;
- struct ncplane *inter = ncplane_create(notcurses_stdplane(ui->nc), &opts);
-
- u32 left = 0, right = 0;
- struct cmc_view_resource *resource;
- switch (view->preview.mode) {
- case CMC_VIEW_SINGLE: {
- resource = view->preview.resources[0];
- resource->vopts.n = inter;
- ncvisual_geom(ui->nc, resource->v, &resource->vopts, &resource->geom);
- // rcellx == width case very untested.
- left += resource->geom.rcelly + (s32)((resource->geom.rcellx != view->preview.width) ? 1 : -1);
- break;
- }
- case CMC_VIEW_PARTITION: {
- ncplane_resize_simple(inter, opts.rows, partition_width);
-
- resource = view->preview.resources[0];
- resource->vopts.n = inter;
- ncvisual_geom(ui->nc, resource->v, &resource->vopts, &resource->geom);
- left += resource->geom.rcelly + 1;
-
- resource = view->preview.resources[1];
- resource->vopts.n = inter;
- ncvisual_geom(ui->nc, resource->v, &resource->vopts, &resource->geom);
- right += resource->geom.rcelly + 1;
-
- if (view->preview.resources[2]) {
- resource = view->preview.resources[2];
- resource->vopts.n = inter;
- ncvisual_geom(ui->nc, resource->v, &resource->vopts, &resource->geom);
- left += resource->geom.rcelly + 1;
- }
-
- if (view->preview.resources[3]) {
- resource = view->preview.resources[3];
- resource->vopts.n = inter;
- ncvisual_geom(ui->nc, resource->v, &resource->vopts, &resource->geom);
- right += resource->geom.rcelly + 1;
- }
-
- break;
- }
- }
-
- ncplane_destroy(inter);
-
- view->preview.height = AL_MAX(right, left);
-
- return rows + view->preview.height;
-}
-
-static void date_to_relative_date(struct sho_post *post, char *out)
-{
- struct sho_post_date *created = NULL;
- struct sho_post_date *date;
- al_array_foreach_ptr(post->dates, i, date) {
- if (date->type == SHOKI_DATE_CREATED) {
- created = date;
- break;
- }
- }
- if (!created) return;
- f64 seconds = (aki_get_timestamp() / 1000000.0 - created->timestamp);
- s64 minutes = seconds / 60L;
- s64 hours = minutes / 60L;
- s64 days = hours / 24L;
- if (days > 0) {
- al_sprintf(out, "%lud", days);
- } else if (hours > 0) {
- al_sprintf(out, "%luh", hours);
- } else if (minutes > 0) {
- al_sprintf(out, "%lum", minutes);
- } else {
- al_sprintf(out, "%lus", (s64)seconds);
- }
-}
-
-static void number_to_shorthand(s64 number, char *out)
-{
- if (number >= 1000000000) {
- al_sprintf(out, "%.1fB", number / 1000000000.f);
- } else if (number >= 1000000) {
- al_sprintf(out, "%.1fM", number / 1000000.f);
- } else if (number >= 1000) {
- al_sprintf(out, "%.1fK", number / 1000.f);
- } else {
- al_sprintf(out, "%ld", number);
- }
-}
-
-static void draw_tweet_resources(struct cmc_ui *ui, struct cmc_view_twitter *view)
-{
- u32 partition_width = view->preview.width / 2;
- struct cmc_view_resource *resource;
- switch (view->preview.mode) {
- case CMC_VIEW_NONE:
- break;
- case CMC_VIEW_SINGLE: {
- resource = view->preview.resources[0];
- ncplane_resize_simple(view->preview.p[0], resource->geom.rcelly + 1, view->preview.width);
- ncplane_move_yx(view->preview.p[0], view->text.height, view->preview.x);
- resource->vopts.n = view->preview.p[0];
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
- break;
- }
- case CMC_VIEW_PARTITION: {
- resource = view->preview.resources[0];
- resource->vopts.n = view->preview.p[0];
- ncplane_resize_simple(view->preview.p[0], resource->geom.rcelly + 1, partition_width);
- ncplane_move_yx(view->preview.p[0], view->text.height, view->preview.x);
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
-
- resource = view->preview.resources[1];
- ncplane_resize_simple(view->preview.p[1], resource->geom.rcelly + 1, partition_width);
- ncplane_move_yx(view->preview.p[1], view->text.height, (view->preview.x + view->preview.resources[0]->geom.rcellx) + 3);
- resource->vopts.n = view->preview.p[1];
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
-
- if (view->preview.resources[2]) {
- resource = view->preview.resources[2];
- ncplane_resize_simple(view->preview.p[2], resource->geom.rcelly + 1, partition_width);
- ncplane_move_yx(view->preview.p[2], view->preview.resources[0]->geom.rcelly + view->text.height + 2, view->preview.x);
- resource->vopts.n = view->preview.p[2];
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
- }
-
- if (view->preview.resources[3]) {
- resource = view->preview.resources[3];
- ncplane_resize_simple(view->preview.p[3], resource->geom.rcelly + 1, partition_width);
- ncplane_move_yx(view->preview.p[3], view->preview.resources[1]->geom.rcelly + view->text.height + 2, (view->preview.x + view->preview.resources[2]->geom.rcellx) + 3);
- resource->vopts.n = view->preview.p[3];
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
- }
-
- break;
- }
- }
-
- if (view->profile.resource && view->profile.resource->v) {
- struct cmc_view_resource *resource = view->profile.resource;
- ncplane_resize_simple(view->profile.p, (PROFILE_SIZE + 1) / 2, PROFILE_SIZE);
- ncplane_move_yx(view->profile.p, view->text.y, PROFILE_SIZE - 2);
- resource->vopts.n = view->profile.p;
- ncvisual_blit(ui->nc, resource->v, &resource->vopts);
- }
-}
-
-void cmc_draw_tweet_func(void *userdata, struct cmc_view *view, u32 y)
-{
- struct cmc_ui *ui = (struct cmc_ui *)userdata;
- struct cmc_search *search = ui->search.search;
- ncplane_reparent_family(view->container, ui->p);
- ncplane_move_yx(view->container, y, 0);
- draw_tweet_resources(ui, (struct cmc_view_twitter *)view);
- view->y = y;
- al_array_push(search->pager.prev, view);
-}
-
-static char format_buf[32];
-
-void cmc_draw_tweet(struct cmc_view_twitter *view, struct ncplane *container, u32 rows, u32 width)
-{
- struct sho_post *post = view->v.post;
- struct sho_post *repost = view->repost;
-
- ncplane_resize_simple(container, rows, width);
-
- ncplane_resize_simple(view->text.p, view->text.height, width);
- ncplane_move_yx(view->text.p, 0, 0);
-
- s32 offset = TEXT_OFFSET;
-
- if (repost) {
- const wchar_t *retweet = L"⮤⮧";
- ncplane_set_styles(view->text.p, NCSTYLE_ITALIC);
- ncplane_putwstr_yx(view->text.p, 0, offset - 3, retweet);
- ncplane_set_styles(view->text.p, NCSTYLE_NONE);
- ncplane_putwstr_yx(view->text.p, 0, offset, &al_wstr_at(&repost->author.display_name, 0));
- }
-
- ncplane_set_styles(view->text.p, NCSTYLE_BOLD);
-
- ncplane_putwstr_yx(view->text.p, view->text.y, offset, &al_wstr_at(&post->author.display_name, 0));
- offset += al_wstr_width(&post->author.display_name) + 1;
-
- ncplane_set_styles(view->text.p, NCSTYLE_NONE);
- ncplane_putwstr_yx(view->text.p, view->text.y, offset, &al_wstr_at(&post->author.username, 0));
- offset += al_wstr_width(&post->author.username) + 1;
-
- ncplane_putwstr_yx(view->text.p, view->text.y, offset, L"∙");
- offset += 2;
-
- date_to_relative_date(post, format_buf);
- ncplane_putstr_yx(view->text.p, view->text.y, offset, format_buf);
-
- u32 text_y = view->text.y + 1, text_x = TEXT_OFFSET;
- for (u32 i = 0; i < post->text.len; i++) {
- wchar_t wc = al_wstr_at(&post->text, i);
- s32 wcwidth = al_wchar_width(wc);
- bool newline = wc == L'\n';
- if (newline || text_x + wcwidth > width) {
- text_y++;
- text_x = TEXT_OFFSET;
- }
- if (newline) continue;
- ncplane_putwc_yx(view->text.p, text_y, text_x, wc);
- text_x += wcwidth;
- }
-
- ncplane_resize_simple(view->stats.p, 1, view->text.width);
- ncplane_move_yx(view->stats.p, rows - 1, TEXT_OFFSET);
-
- u32 part = 10;
- offset = 0;
-
- if (post->comments.set) {
- const wchar_t *comment = L"🗩";
- ncplane_set_styles(view->stats.p, NCSTYLE_ITALIC);
- ncplane_putwstr_yx(view->stats.p, 0, offset, comment);
- ncplane_set_styles(view->stats.p, NCSTYLE_NONE);
- number_to_shorthand(post->comments.i, format_buf);
- ncplane_putstr_yx(view->stats.p, 0, offset + 3, format_buf);
- }
- offset += part;
-
- if (post->reposts.set) {
- const wchar_t *retweet = L"⮤⮧";
- ncplane_set_styles(view->stats.p, NCSTYLE_ITALIC);
- ncplane_putwstr_yx(view->stats.p, 0, offset, retweet);
- ncplane_set_styles(view->stats.p, NCSTYLE_NONE);
- number_to_shorthand(post->reposts.i, format_buf);
- ncplane_putstr_yx(view->stats.p, 0, offset + 3, format_buf);
- }
- offset += part;
-
- if (post->likes.set) {
- //const wchar_t *like = L"❤";
- const wchar_t *like = L"♥";
- ncplane_set_styles(view->stats.p, NCSTYLE_ITALIC);
- ncplane_putwstr_yx(view->stats.p, 0, offset, like);
- ncplane_set_styles(view->stats.p, NCSTYLE_NONE);
- number_to_shorthand(post->likes.i, format_buf);
- ncplane_putstr_yx(view->stats.p, 0, offset + 2, format_buf);
- }
-}
-
-static void get_post_and_maybe_repost(struct cmc_ui *ui, str *unique_id, struct sho_post **post, struct sho_post **repost)
-{
- struct sho_post_cache *cache = &ui->c->client.cache;
- *post = sho_post_cache_get(cache, unique_id);
- *repost = NULL;
- if ((*post)->type == SHOKI_POST_REPOST) {
- *repost = *post;
- *post = sho_post_cache_get(cache, &(*post)->post.unique_id);
- }
-}
-
-static void strip_link_from_tweet(struct sho_post *post)
-{
- wstr *check = al_wstr_c(L"https://t.co/");
- s32 index = al_wstr_rfind(&post->text, L':');
- if (index < 5) return;
- index -= 5; // [h]ttps:// (if matched).
- if (al_wstr_cmp(&post->text, check, index, check->len) == 0) {
- al_wstr_at(&post->text, index) = L'\0';
- post->text.len = index;
- }
-}
-
-struct cmc_view_twitter *cmc_create_view_twitter(struct cmc_ui *ui, str *unique_id)
-{
- struct cmc_view_twitter *view = al_alloc_object(struct cmc_view_twitter);
- get_post_and_maybe_repost(ui, unique_id, &view->v.post, &view->repost);
-
- if (view->v.post->media.size > 0) {
- strip_link_from_tweet(view->v.post);
- }
-
- view->v.rows = 0;
- view->v.y = 0;
- view->v.pending_requests = 0;
-
- struct ncplane_options default_options = { 0 };
- default_options.cols = 1;
- default_options.rows = 1;
- default_options.x = 0;
- default_options.y = 0;
-
- view->v.container = ncpile_create(ui->nc, &default_options);
- view->text.p = ncplane_create(view->v.container, &default_options);
- view->profile.p = ncplane_create(view->v.container, &default_options);
- for (u32 i = 0; i < 4; i++) {
- view->preview.p[i] = ncplane_create(view->v.container, &default_options);
- }
- view->stats.p = ncplane_create(view->v.container, &default_options);
-
- struct sho_post *post = view->v.post;
- view->profile.resource = cmc_get_resource_from_cache(&ui->resources, &view->v, &post->author.unique_id, 0);
- struct sho_post_media *media;
- al_array_foreach_ptr(post->media, i, media) {
- (void)media;
- view->preview.resources[i] = cmc_get_resource_from_cache(&ui->resources, &view->v, &post->unique_id, i);
- }
-
- switch (post->media.size) {
- case 0:
- view->preview.mode = CMC_VIEW_NONE;
- break;
- case 1:
- view->preview.mode = CMC_VIEW_SINGLE;
- break;
- default:
- view->preview.mode = CMC_VIEW_PARTITION;
- break;
- }
-
- return view;
-}
diff --git a/src/fruits/cmc/tui/view_twitter.h b/src/fruits/cmc/tui/view_twitter.h
deleted file mode 100644
index 9792826..0000000
--- a/src/fruits/cmc/tui/view_twitter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "ui.h"
-#include "view.h"
-
-struct cmc_view_twitter {
- struct cmc_view v;
- struct sho_post *repost;
- struct {
- u32 width;
- u32 height;
- u32 y;
- struct ncplane *p;
- } text;
- struct {
- struct ncplane *p;
- struct cmc_view_resource *resource;
- } profile;
- struct {
- u8 mode;
- u32 width;
- u32 height;
- u32 x;
- struct ncplane *p[4];
- struct cmc_view_resource *resources[4];
- } preview;
- struct {
- struct ncplane *p;
- } stats;
-};
-
-struct cmc_view_twitter *cmc_create_view_twitter(struct cmc_ui *ui, str *unique_id);
-void cmc_draw_tweet(struct cmc_view_twitter *view, struct ncplane *container, u32 rows, u32 width);
-u32 cmc_layout_tweet(struct cmc_ui *ui, struct cmc_view_twitter *view, u32 width);
-void cmc_draw_tweet_func(void *userdata, struct cmc_view *view, u32 y);