summaryrefslogtreecommitdiff
path: root/src/fruits/cmc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fruits/cmc')
-rw-r--r--src/fruits/cmc/cmc.c78
-rw-r--r--src/fruits/cmc/cmc.h17
-rw-r--r--src/fruits/cmc/meson.build5
-rw-r--r--src/fruits/cmc/ui/pane_search.c39
-rw-r--r--src/fruits/cmc/ui/tile.h5
-rw-r--r--src/fruits/cmc/ui/ui.c67
-rw-r--r--src/fruits/cmc/ui/ui.h25
7 files changed, 181 insertions, 55 deletions
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c
index 724a489..3c62ba8 100644
--- a/src/fruits/cmc/cmc.c
+++ b/src/fruits/cmc/cmc.c
@@ -1,10 +1,8 @@
#include <aki/common.h>
#include <aki/event_loop.h>
-#include "../../libclient/client.h"
-#include "../../server/common.c"
#include "../../portal/src/packet_ext.h"
-#include "../../portal/src/post_cache.h"
+#include "../../server/common.c"
#include "cmc.h"
@@ -12,18 +10,8 @@
enum {
CLI_OPEN_UI = 0,
- CLI_ADD
-};
-
-struct cmc {
- struct aki_event_loop loop;
- u8 command;
- array(str) args;
- struct camu_client client;
- struct camu_post_cache cache;
- array(struct cmc_search *) searches;
- struct cmc_ui ui;
- struct aki_poll input_poll;
+ CLI_ADD,
+ CLI_SEARCH
};
static struct cmc_search *get_search_by_id(struct cmc *c, s32 id)
@@ -35,21 +23,20 @@ static struct cmc_search *get_search_by_id(struct cmc *c, s32 id)
return NULL;
}
-static void input_poll_callback(void *userdata, s32 revents)
+static void parse_user_state(struct cmc *c, struct aki_packet *packet)
{
- struct cmc *c = (struct cmc *)userdata;
- (void)revents;
- struct ncinput input;
- do {
- if (!cmc_ui_read_input(&c->ui, &input)) break;
- if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
- switch (input.id) {
- case 'q':
- aki_event_loop_break_one(&c->loop);
- break;
- }
- }
- } while (1);
+ u32 size = aki_packet_read_u32(packet);
+ for (u32 i = 0; i < size; i++) {
+ struct cmc_search *search = al_alloc_object(struct cmc_search);
+ search->id = aki_packet_read_s32(packet);
+ str s;
+ aki_packet_read_str(packet, &s);
+ al_str_clone(&search->module, &s);
+ aki_packet_read_str(packet, &s);
+ al_str_clone(&search->query, &s);
+ al_array_init(search->pages);
+ al_array_push(c->searches, search);
+ }
}
static void client_callback(void *userdata, u8 op, void *opaque)
@@ -57,19 +44,28 @@ static void client_callback(void *userdata, u8 op, void *opaque)
struct cmc *c = (struct cmc *)userdata;
switch (op) {
case CAMU_CLIENT_LOGIN: {
+ struct aki_packet *packet = (struct aki_packet *)opaque;
switch (c->command) {
case CLI_OPEN_UI:
- if (!cmc_ui_init(&c->ui)) {
+ parse_user_state(c, packet);
+ if (!cmc_ui_init(&c->ui, &c->loop, c)) {
aki_event_loop_break_one(&c->loop);
}
- aki_poll_init(&c->input_poll, input_poll_callback, c);
- aki_poll_set(&c->input_poll, cmc_ui_get_input_fd(&c->ui), AKI_POLL_READ);
- aki_poll_start(&c->input_poll, &c->loop);
break;
case CLI_ADD: {
str *arg;
al_array_foreach_ptr(c->args, i, arg) {
camu_client_add_from_path(&c->client, al_str_c("default"), arg);
+ al_str_free(arg);
+ }
+ camu_client_disconnect(&c->client);
+ break;
+ }
+ case CLI_SEARCH: {
+ str *arg;
+ al_array_foreach_ptr(c->args, i, arg) {
+ camu_client_create_search(&c->client, al_str_c("youtube"), arg);
+ al_str_free(arg);
}
camu_client_disconnect(&c->client);
break;
@@ -136,11 +132,22 @@ static bool parse_cmd(s32 argc, wchar_t **argv)
al_array_push(c.args, arg);
}
}
+ } else if (al_str_eq(al_str_cr(argv[1]), al_str_c("search"))) {
+ if (argc < 3) return false;
+ c.command = CLI_SEARCH;
+ str query;
+ al_str_from(&query, "");
+ for (s32 i = 2; i < argc; i++) {
+ al_str_cat(&query, al_str_cr(argv[i]));
+ if (i != argc - 1) {
+ al_str_cat(&query, al_str_c(" "));
+ }
+ }
+ al_array_push(c.args, query);
}
return true;
}
-
#ifndef _WIN32
s32 main(s32 argc, char *argv[])
#else
@@ -152,12 +159,11 @@ s32 wmain(s32 argc, wchar_t **argv)
aki_event_loop_init(&c.loop);
al_array_init(c.args);
+ if (!parse_cmd(argc, argv)) return EXIT_FAILURE;
camu_post_cache_init(&c.cache);
al_array_init(c.searches);
- if (!parse_cmd(argc, argv)) return EXIT_FAILURE;
-
c.client.callback = client_callback;
c.client.userdata = &c;
if (!camu_client_login(&c.client, &c.loop, CAMU_LOCAL_TYPE, CAMU_LOCAL_ADDR, CAMU_PORT, al_str_c("andrew"))) {
diff --git a/src/fruits/cmc/cmc.h b/src/fruits/cmc/cmc.h
index a9c8544..353bd87 100644
--- a/src/fruits/cmc/cmc.h
+++ b/src/fruits/cmc/cmc.h
@@ -4,6 +4,11 @@
#include <al/array.h>
#include <al/str.h>
+#include "../../libclient/client.h"
+#include "../../portal/src/post_cache.h"
+
+#include "ui/ui.h"
+
struct cmc_search_page {
u32 num;
array(str) list;
@@ -11,5 +16,17 @@ struct cmc_search_page {
struct cmc_search {
s32 id;
+ str module;
+ str query;
array(struct cmc_search_page *) pages;
};
+
+struct cmc {
+ struct aki_event_loop loop;
+ u8 command;
+ array(str) args;
+ struct camu_client client;
+ struct camu_post_cache cache;
+ array(struct cmc_search *) searches;
+ struct cmc_ui ui;
+};
diff --git a/src/fruits/cmc/meson.build b/src/fruits/cmc/meson.build
index 627391e..76efff5 100644
--- a/src/fruits/cmc/meson.build
+++ b/src/fruits/cmc/meson.build
@@ -8,7 +8,10 @@ endif
use_tui = true
if use_tui
- cmc_src += ['ui/ui.c']
+ cmc_src += [
+ 'ui/ui.c',
+ 'ui/pane_search.c',
+ ]
cmc_deps += [dependency('notcurses')]
endif
diff --git a/src/fruits/cmc/ui/pane_search.c b/src/fruits/cmc/ui/pane_search.c
new file mode 100644
index 0000000..cc549e1
--- /dev/null
+++ b/src/fruits/cmc/ui/pane_search.c
@@ -0,0 +1,39 @@
+#include "../cmc.h"
+
+#include "ui.h"
+
+void cmc_sp_init(struct cmc_ui *ui)
+{
+ if (ui->c->searches.size > 0) {
+ ui->sp.search = al_array_at(ui->c->searches, 0);
+ }
+ cmc_sp_layout(ui, notcurses_stdplane(ui->nc));
+}
+
+void cmc_sp_layout(struct cmc_ui *ui, struct ncplane *parent)
+{
+ if (ui->sp.n) ncplane_destroy(ui->sp.n);
+ struct ncplane_options nopts = {
+ .rows = ui->term_rows,
+ .cols = ui->term_cols,
+ .x = 0,
+ .y = 0
+ };
+ ui->sp.n = ncplane_create(parent, &nopts);
+}
+
+bool cmc_sp_handle_input(struct cmc_ui *ui, struct ncinput *input)
+{
+ (void)ui;
+ (void)input;
+ return true;
+}
+
+void cmc_sp_render(struct cmc_ui *ui)
+{
+ if (ui->sp.search) {
+ char *c_str = al_str_to_c_str(&ui->sp.search->query);
+ ncplane_putstr_yx(ui->sp.n, 0, 0, c_str);
+ al_free(c_str);
+ }
+}
diff --git a/src/fruits/cmc/ui/tile.h b/src/fruits/cmc/ui/tile.h
new file mode 100644
index 0000000..6f15c7d
--- /dev/null
+++ b/src/fruits/cmc/ui/tile.h
@@ -0,0 +1,5 @@
+#pragma once
+
+struct cmc_tile {
+
+};
diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c
index a838f96..58d630f 100644
--- a/src/fruits/cmc/ui/ui.c
+++ b/src/fruits/cmc/ui/ui.c
@@ -2,28 +2,69 @@
#include "ui.h"
-bool cmc_ui_init(struct cmc_ui *ui)
+static s32 resize_cb(struct ncplane *p)
{
- al_memset(ui, 0, sizeof(struct cmc_ui));
- if (!(ui->nc = notcurses_init(NULL, stdin))) {
- return false;
- }
- return true;
+ struct cmc_ui *ui = (struct cmc_ui *)ncplane_userptr(p);
+ (void)ui;
+ return 0;
}
-s32 cmc_ui_get_input_fd(struct cmc_ui *ui)
-{
- return notcurses_inputready_fd(ui->nc);
-}
-
-bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input)
+static bool read_input(struct cmc_ui *ui, struct ncinput *input)
{
al_memset(input, 0, sizeof(struct ncinput));
u32 ret = notcurses_get_nblock(ui->nc, input);
return !(ret == (u32)-1 || ret == 0);
}
+static void input_poll_callback(void *userdata, s32 revents)
+{
+ struct cmc_ui *ui = (struct cmc_ui *)userdata;
+ (void)revents;
+ struct ncinput input;
+ do {
+ if (!read_input(ui, &input)) break;
+ bool do_render = false;
+ if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
+ switch (input.id) {
+ case 'q':
+ aki_event_loop_break_one(ui->loop);
+ break;
+ }
+ }
+ switch (ui->pane) {
+ case CMC_PANE_SEARCH:
+ if (cmc_sp_handle_input(ui, &input)) {
+ cmc_sp_render(ui);
+ do_render |= true;
+ }
+ }
+ if (do_render) {
+ notcurses_render(ui->nc);
+ }
+ } while (1);
+}
+
+bool cmc_ui_init(struct cmc_ui *ui, struct aki_event_loop *loop, struct cmc *c)
+{
+ al_memset(ui, 0, sizeof(struct cmc_ui));
+ ui->c = c;
+ if (!(ui->nc = notcurses_init(NULL, stdin))) {
+ return false;
+ }
+ ui->loop = loop;
+ notcurses_stddim_yx(ui->nc, &ui->term_rows, &ui->term_cols);
+ cmc_sp_init(ui);
+ struct ncplane *stdplane = notcurses_stdplane(ui->nc);
+ ncplane_set_resizecb(stdplane, resize_cb);
+ ncplane_set_userptr(stdplane, ui);
+ aki_poll_init(&ui->input_poll, input_poll_callback, ui);
+ aki_poll_set(&ui->input_poll, notcurses_inputready_fd(ui->nc), AKI_POLL_READ);
+ aki_poll_start(&ui->input_poll, ui->loop);
+ ui->pane = CMC_PANE_SEARCH;
+ return true;
+}
+
void cmc_ui_close(struct cmc_ui *ui)
{
- notcurses_stop(ui->nc);
+ if (ui->nc) notcurses_stop(ui->nc);
}
diff --git a/src/fruits/cmc/ui/ui.h b/src/fruits/cmc/ui/ui.h
index 4af222e..1a49985 100644
--- a/src/fruits/cmc/ui/ui.h
+++ b/src/fruits/cmc/ui/ui.h
@@ -1,18 +1,33 @@
#pragma once
#include <al/types.h>
+#include <aki/event_loop.h>
#include <notcurses/notcurses.h>
+enum {
+ CMC_PANE_SEARCH = 0,
+};
+
+struct cmc;
struct cmc_ui {
struct notcurses *nc;
+ struct aki_event_loop *loop;
u32 term_cols;
u32 term_rows;
bool pending_layout;
+ struct aki_poll input_poll;
+ u8 pane;
+ struct {
+ struct ncplane *n;
+ struct cmc_search *search;
+ } sp; // search pane.
+ struct cmc *c;
};
-bool cmc_ui_init(struct cmc_ui *ui);
-
-s32 cmc_ui_get_input_fd(struct cmc_ui *ui);
-bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input);
-
+bool cmc_ui_init(struct cmc_ui *ui, struct aki_event_loop *loop, struct cmc *c);
void cmc_ui_close(struct cmc_ui *ui);
+
+void cmc_sp_init(struct cmc_ui *ui);
+void cmc_sp_layout(struct cmc_ui *ui, struct ncplane *parent);
+bool cmc_sp_handle_input(struct cmc_ui *ui, struct ncinput *input);
+void cmc_sp_render(struct cmc_ui *ui);