summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--include/config.hpp5
-rw-r--r--libs/imgui/imgui.cpp4
-rw-r--r--libs/imgui/imgui.h2
-rw-r--r--src/importer.cpp10
-rw-r--r--src/locales/en.cpp2
-rw-r--r--src/main_linux.cpp4
-rw-r--r--src/providers/MailerSend.cpp11
-rw-r--r--src/ui/imgui_extensions.cpp14
-rw-r--r--src/ui/ui_expenses.cpp20
-rw-r--r--src/ui/ui_invoices.cpp13
11 files changed, 60 insertions, 27 deletions
diff --git a/TODO b/TODO
index a5a0dea..17dc4e4 100644
--- a/TODO
+++ b/TODO
@@ -18,6 +18,8 @@ Testing:
- write tests for document saving
Features:
+- status window for ongoing requests, used can click on item when result is ready. Should be usefull for batch imports.
+- implement gemini and perplexity api backends
- Refactor contact and project UI to be like invoice & expenses
- Handle invalid api key response from AI backends and display in settings UI
- error log for tax report to display invoices not yet supported for tax generation or invoices with invalid tax rates
diff --git a/include/config.hpp b/include/config.hpp
index 84773d1..ed1feed 100644
--- a/include/config.hpp
+++ b/include/config.hpp
@@ -30,8 +30,9 @@
#define u32 uint32_t
#define u64 uint64_t
-#define SIMULATE_EMAIL_FAILURE 1
-#define SIMULATE_EMAIL 1
+#define SIMULATE_AI_IMPORT 1
+#define SIMULATE_EMAIL_FAILURE 0
+#define SIMULATE_EMAIL 0
#define SIMULATE_SLOW_DISK 0
#define SIMULATE_WRITE_FAILURE 0
diff --git a/libs/imgui/imgui.cpp b/libs/imgui/imgui.cpp
index e42993c..a4c7e56 100644
--- a/libs/imgui/imgui.cpp
+++ b/libs/imgui/imgui.cpp
@@ -16680,7 +16680,7 @@ void ImGui::DebugBreakButtonTooltip(bool keyboard_only, const char* description_
// From https://github.com/ocornut/imgui/issues/1901#issuecomment-444929973
void ImGui::LoadingIndicatorCircle(const float indicator_radius,
const ImVec4& main_color, const ImVec4& backdrop_color,
- const int circle_count, const float speed) {
+ const int circle_count, const float speed, float circle_radius = 0.0f) {
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) {
return;
@@ -16690,7 +16690,7 @@ void ImGui::LoadingIndicatorCircle(const float indicator_radius,
//const ImGuiID id = window->GetID(label);
const ImVec2 pos = window->DC.CursorPos;
- const float circle_radius = indicator_radius / 12.0f;
+ if (circle_radius == 0.0f) circle_radius = indicator_radius / 12.0f;
const float updated_indicator_radius = indicator_radius - 4.0f * circle_radius;
const ImRect bb(pos, ImVec2(pos.x + indicator_radius * 2.0f, pos.y + indicator_radius * 2.0f));
//ItemSize(bb);
diff --git a/libs/imgui/imgui.h b/libs/imgui/imgui.h
index bfe7b0f..3f4ee8c 100644
--- a/libs/imgui/imgui.h
+++ b/libs/imgui/imgui.h
@@ -380,7 +380,7 @@ namespace ImGui
IMGUI_API void LoadingIndicatorCircleSmall();
IMGUI_API void LoadingIndicatorCircle(const float indicator_radius,
const ImVec4& main_color, const ImVec4& backdrop_color,
- const int circle_count, const float speed);
+ const int circle_count, const float speed, float circle_radius);
// Context creation and access
// - Each context create its own ImFontAtlas by default. You may instance one yourself and pass it to CreateContext() to share a font atlas between contexts.
diff --git a/src/importer.cpp b/src/importer.cpp
index 23bdcbe..0027da9 100644
--- a/src/importer.cpp
+++ b/src/importer.cpp
@@ -210,8 +210,8 @@ static int _ai_document_to_invoice_t(void *arg)
char* file_path = request->file_path;
importer::ai_provider_impl impl = importer::get_ai_provider_implementation(administration::get_active_ai_service().provider);
+ #if !SIMULATE_AI_IMPORT
request->status = importer::import_status::IMPORT_UPLOADING_FILE;
-
char file_id[100];
if (!impl.upload_file(file_path, file_id, 100)) {
request->status = importer::import_status::IMPORT_DONE;
@@ -256,6 +256,14 @@ static int _ai_document_to_invoice_t(void *arg)
request->error = I_ERR_FAILED_QUERY;
return 0;
}
+ #else
+ invoice inv = administration::invoice_create_empty();
+ usleep(5000 * 1000);
+ request->status = importer::import_status::IMPORT_UPLOADING_FILE;
+ usleep(5000 * 1000);
+ request->status = importer::import_status::IMPORT_WAITING_FOR_RESPONSE;
+ usleep(5000 * 1000);
+ #endif
inv.extras.status = invoice_status::INVOICE_RECEIVED;
diff --git a/src/locales/en.cpp b/src/locales/en.cpp
index c03fcc3..673c3b7 100644
--- a/src/locales/en.cpp
+++ b/src/locales/en.cpp
@@ -343,7 +343,7 @@ locale_entry en_locales[] = {
{"settings.services.ai_service.model", "Model"},
{"settings.services.ai_service.apikey", "API key"},
- {"settings.services.ai_service", "Email Service"},
+ {"settings.services.email_service", "Email Service"},
{"settings.services.email_service.provider", "Provider"},
{"settings.services.email_service.apikey", "API key"},
diff --git a/src/main_linux.cpp b/src/main_linux.cpp
index 95177ef..092fd80 100644
--- a/src/main_linux.cpp
+++ b/src/main_linux.cpp
@@ -69,13 +69,13 @@ static void _create_window(bool is_setup_window)
else {
glfwWindowHint(GLFW_RESIZABLE, true);
}
-
+
+ glfwWindowHint(GLFW_SAMPLES, 4);
window = glfwCreateWindow(windowWidth, windowHeight, "OpenBooks", nullptr, nullptr);
if (window == nullptr)
return;
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
- glfwWindowHint(GLFW_SAMPLES, 4);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
diff --git a/src/providers/MailerSend.cpp b/src/providers/MailerSend.cpp
index dbae4c6..fe83aea 100644
--- a/src/providers/MailerSend.cpp
+++ b/src/providers/MailerSend.cpp
@@ -31,7 +31,6 @@ bool _MailerSend_send_email(const char* sender, const char* recipient, const cha
const char *api_key = administration::get_email_service().api_key;
httplib::SSLClient cli("api.mailersend.com", 443);
- cli.enable_server_certificate_verification(false);
cli.set_connection_timeout(15, 0);
size_t body_size = 10000;
@@ -60,9 +59,15 @@ bool _MailerSend_send_email(const char* sender, const char* recipient, const cha
httplib::Result res = cli.Post("/v1/email", headers, body, "application/json");
memops::unalloc(body);
+
+ if (!res) {
+ logger::error("Failed to send email. Reason: Timeout");
+ return E_ERR_FAILED_REQUEST;
+ }
- if (!res || (res->status != 200 && res->status != 202)) {
- logger::error("Failed to send email.");
+ if (res->status != 200 && res->status != 202) {
+ int status = res->status;
+ logger::error("Failed to send email. Status code: '%d'", status);
return E_ERR_FAILED_REQUEST;
}
diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp
index 496bbe2..dee36a7 100644
--- a/src/ui/imgui_extensions.cpp
+++ b/src/ui/imgui_extensions.cpp
@@ -41,7 +41,7 @@ namespace ImGui
float radius = 10.0f;
const ImVec4 col = ImGui::GetStyleColorVec4(ImGuiCol_LoadingIndicatorFg);
const ImVec4 bg = ImGui::GetStyleColorVec4(ImGuiCol_LoadingIndicatorBg);
- ImGui::LoadingIndicatorCircle(radius, bg, col, 6, 4.0f);
+ ImGui::LoadingIndicatorCircle(radius, bg, col, 6, 4.0f, 0.0f);
}
bool CheckboxX(const char* label, bool* v, bool disabled, bool show_loading_indicator_while_disabled)
@@ -85,14 +85,14 @@ namespace ImGui
static void DrawSuccessMark(int bWidth = 0, bool isButton = true)
{
ImGui::PushStyleColor(ImGuiCol_Text, config::colors::COLOR_SUCCESS);
- if (isButton) ImGui::Button(ICON_FA_CHECK_SQUARE, ImVec2(bWidth, 0)); else ImGui::Text("√");
+ if (isButton) ImGui::Button(ICON_FA_CHECK_SQUARE, ImVec2(bWidth, 0)); else ImGui::Text(ICON_FA_CHECK_SQUARE);
ImGui::PopStyleColor();
}
static void DrawFailureMark(int bWidth = 0, bool isButton = true)
{
ImGui::PushStyleColor(ImGuiCol_Text, config::colors::COLOR_ERROR);
- if (isButton) ImGui::Button(ICON_FA_BAN, ImVec2(bWidth, 0)); else ImGui::Text("√");
+ if (isButton) ImGui::Button(ICON_FA_BAN, ImVec2(bWidth, 0)); else ImGui::Text(ICON_FA_BAN);
ImGui::PopStyleColor();
}
@@ -796,7 +796,7 @@ namespace ImGui
{
static bool is_new_request = false;
static bool show_status_change = false;
- static time_t status_changed_at = 0;
+ static double status_changed_at = 0;
static e_err last_err;
if (active_request && active_request->status == exporter::export_status::EXPORT_DONE && is_new_request)
@@ -804,7 +804,7 @@ namespace ImGui
is_new_request = false;
show_status_change = true;
last_err = active_request->error;
- status_changed_at = time(NULL);
+ status_changed_at = ImGui::GetTime();
}
if (active_request && active_request->status != exporter::export_status::EXPORT_DONE) {
@@ -834,14 +834,14 @@ namespace ImGui
}
else {
DrawFailureMark(0, false);
- ImGui::Text(locale::get("form.failure"));
+ ImGui::Text(locale::get("form.failed"));
}
ImGui::EndComboPreview();
}
}
ImGui::EndDisabled();
- if (difftime(time(NULL), status_changed_at) > 0.5f) {
+ if (ImGui::GetTime() - status_changed_at >= 1.0f) {
show_status_change = false;
}
}
diff --git a/src/ui/ui_expenses.cpp b/src/ui/ui_expenses.cpp
index 6ac043f..64dbc18 100644
--- a/src/ui/ui_expenses.cpp
+++ b/src/ui/ui_expenses.cpp
@@ -20,6 +20,7 @@
#include "ui.hpp"
#include "memops.hpp"
+#include "assets.hpp"
#include "strops.hpp"
#include "locales.hpp"
#include "importer.hpp"
@@ -431,6 +432,9 @@ static void draw_import_request()
}
}
+ ai_service ai = administration::get_active_ai_service();
+ importer::ai_provider_impl ai_impl = importer::get_ai_provider_implementation(ai.provider);
+
ImGui::PushFont(ui::fontBig);
ImVec2 windowSize = ImGui::GetWindowSize();
@@ -439,17 +443,25 @@ static void draw_import_request()
const char* text = importer::status_to_string(active_import_request->status);
if (active_import_request->error != I_ERR_SUCCESS) text = importer::error_to_string(active_import_request->error);
ImVec2 textSize = ImGui::CalcTextSize(text);
- ImGui::SetCursorPos(ImVec2((windowSize.x - textSize.x) * 0.5f,
+
+ ImGui::SetCursorPos(ImVec2((windowSize.x - textSize.x) * 0.5f - 24,
(windowSize.y) * 0.5f - radius - 40.0f));
+ ImGui::Image(assets::load_image(ai_impl.icon_name), ImVec2(24, 24));
+
+
+ ImGui::SetCursorPos(ImVec2((windowSize.x - textSize.x) * 0.5f + 10,
+ (windowSize.y) * 0.5f - radius - 40.0f - 2));
ImGui::Text(text);
if (active_import_request->error == I_ERR_SUCCESS) {
ImGui::SetCursorPos(ImVec2((windowSize.x - radius*2) * 0.5f,
(windowSize.y - radius*2) * 0.5f));
- const ImVec4 col = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
- const ImVec4 bg = ImGui::GetStyleColorVec4(ImGuiCol_Button);
- ImGui::LoadingIndicatorCircle(radius, bg, col, 10, 4.0f);
+ const ImVec4 col = ImGui::GetStyleColorVec4(ImGuiCol_LoadingIndicatorFg);
+ const ImVec4 bg = ImGui::GetStyleColorVec4(ImGuiCol_LoadingIndicatorBg);
+ ImGui::LoadingIndicatorCircle(radius, bg, col, 10, 4.0f, 0.0f);
+
+ ImGui::Dummy(ImVec2(200,200));
}
ImGui::PopFont();
diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp
index ffdfb9b..e7872d1 100644
--- a/src/ui/ui_invoices.cpp
+++ b/src/ui/ui_invoices.cpp
@@ -49,11 +49,13 @@ static void _set_active_invoice(invoice inv)
void ui::destroy_invoices()
{
- memops::unalloc(invoice_items_buffer);
- memops::unalloc(activity_buffer);
+ // Currently causes crash because of multithreaded imports.
+ // Main thread needs to be locked.
+ //memops::unalloc(invoice_items_buffer);
+ //memops::unalloc(activity_buffer);
- invoice_items_buffer = 0;
- activity_buffer = 0;
+ //invoice_items_buffer = 0;
+ //activity_buffer = 0;
}
void ui::setup_invoices()
@@ -497,6 +499,9 @@ static void draw_send_options()
_reload_activities();
}
+ else {
+ // @TODO show failure reason
+ }
});
}
// if (ImGui::Selectable(locale::get("ui.sendAs.einvoice"), false)) {