diff options
Diffstat (limited to 'clients/ui.c')
| -rw-r--r-- | clients/ui.c | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/clients/ui.c b/clients/ui.c index e6f6e07..cda0883 100644 --- a/clients/ui.c +++ b/clients/ui.c @@ -472,26 +472,9 @@ static void safe_fname(const char *in, char *out, size_t n) out[o] = '\0'; } -static int write_pdf_b64(const char *b64, const char *path) -{ - unsigned char *data = NULL; - size_t len = 0; - if (!b64 || util_b64_decode(b64, strlen(b64), &data, &len) != 0) - return -1; - FILE *fp = fopen(path, "wb"); - if (!fp) { - free(data); - return -1; - } - size_t wrote = fwrite(data, 1, len, fp); - fclose(fp); - free(data); - return wrote == len ? 0 : -1; -} - -/* Open a saved PDF with xdg-open when a desktop session is present; +/* Open a saved file with xdg-open when a desktop session is present; otherwise (or on fork failure) show where it was saved. */ -static void open_pdf(const char *path, const char *title) +static void open_saved(const char *path, const char *title) { const char *display = getenv("DISPLAY"); const char *wayland = getenv("WAYLAND_DISPLAY"); @@ -515,8 +498,8 @@ static void open_pdf(const char *path, const char *title) tui_message(title, "Sparad: %s", path); } -void pdf_save_and_open(const char *b64, const char *filename, - const char *title) +static void save_cache_and_open(const unsigned char *data, size_t n, + const char *filename, const char *title) { char dir[512], path[700], safe[600]; pdf_cache_dir(dir, sizeof dir); @@ -526,11 +509,80 @@ void pdf_save_and_open(const char *b64, const char *filename, return; } config_mkdirs(path); - if (write_pdf_b64(b64, path) != 0) { + FILE *fp = fopen(path, "wb"); + if (!fp || (n > 0 && fwrite(data, 1, n, fp) != n)) { + if (fp) + fclose(fp); tui_message(title, "Kunde inte spara %s", path); return; } - open_pdf(path, title); + fclose(fp); + open_saved(path, title); +} + +void file_save_and_open(const char *b64, const char *filename, + const char *title) +{ + unsigned char *data = NULL; + size_t n = 0; + if (!b64 || util_b64_decode(b64, strlen(b64), &data, &n) != 0) { + tui_message(title, "Kunde inte avkoda innehållet."); + return; + } + save_cache_and_open(data, n, filename, title); + free(data); +} + +/* Show one attachment: text inline in a pager, anything else through the + desktop viewer (or a message with the saved path). */ +void attachment_open(struct app *a, int64_t att_id) +{ + char args[64]; + snprintf(args, sizeof args, "{\"id\":%lld}", (long long)att_id); + char *resp = + client_rpc(&a->conn, "attachment.get", a->session, a->org, args); + if (!resp || !client_ok(resp)) { + show_error("Kunde inte hämta underlaget", resp); + free(resp); + return; + } + char *fn = jstr_dup(resp, "result.filename"); + char *mime = jstr_dup(resp, "result.mime"); + char *b64 = jstr_dup(resp, "result.content_base64"); + unsigned char *data = NULL; + size_t n = 0; + if (!b64 || util_b64_decode(b64, strlen(b64), &data, &n) != 0) { + tui_message("Underlag", "Kunde inte avkoda innehållet."); + goto done; + } + int is_text = (mime && strncmp(mime, "text/", 5) == 0) || + (n > 0 && bytes_look_text(data, n)); + if (is_text && n <= 256 * 1024) { + char *copy = xmalloc(n + 1); + memcpy(copy, data, n); + copy[n] = '\0'; + tui_pager("Underlag", copy, NULL); + free(copy); + } else { + save_cache_and_open(data, n, fn && *fn ? fn : "underlag", "Underlag"); + } +done: + free(data); + free(b64); + free(mime); + free(fn); + free(resp); +} + +/* Enter on an attachment row: granska or ladda ned. */ +void attachment_view_or_download(struct app *a, int64_t att_id) +{ + static const char *const opts[] = { "Granska", "Ladda ned…" }; + int c = tui_choice_prompt("Underlag: ", opts, 2, 0); + if (c == 0) + attachment_open(a, att_id); + else if (c == 1) + attachment_download(a, att_id); } /* Fetch one attachment, save it to a prompted path and verify its hash. |
