diff --git a/external/solanaceae_message3 b/external/solanaceae_message3 index 53d65a0..c577a1f 160000 --- a/external/solanaceae_message3 +++ b/external/solanaceae_message3 @@ -1 +1 @@ -Subproject commit 53d65a06855129135e5884f50d9983676290ac24 +Subproject commit c577a1fa3d19272d481a0ed4a5b8715524204928 diff --git a/external/solanaceae_tox b/external/solanaceae_tox index dd596bd..5700d9d 160000 --- a/external/solanaceae_tox +++ b/external/solanaceae_tox @@ -1 +1 @@ -Subproject commit dd596bdad8d71654ff21dd3a032d6eb2dd7139a8 +Subproject commit 5700d9d17febedec690dc24193bc65607d8d9fda diff --git a/flake.nix b/flake.nix index c7116bd..e488cfa 100644 --- a/flake.nix +++ b/flake.nix @@ -30,9 +30,12 @@ # for some reason, buildInputs performs some magic an converts them to build dependencies, not runtime dependencies # also, non static dependencies (?? how to ensure ??) dlopenBuildInputs = with pkgs; [ + dbus + xorg.libX11 xorg.libXext xorg.xorgproto + libxkbcommon xorg.libICE xorg.libXi xorg.libXScrnSaver @@ -40,7 +43,10 @@ xorg.libXinerama xorg.libXrandr xorg.libXxf86vm + libGL + + pipewire ]; buildInputs = with pkgs; [ diff --git a/src/chat_gui4.cpp b/src/chat_gui4.cpp index 24c6d66..0bc1b2b 100644 --- a/src/chat_gui4.cpp +++ b/src/chat_gui4.cpp @@ -14,6 +14,7 @@ #include "./media_meta_info_loader.hpp" #include "./sdl_clipboard_utils.hpp" +#include "solanaceae/message3/registry_message_model.hpp" #include #include @@ -22,6 +23,19 @@ #include #include +namespace Components { + + struct UnreadFade { + // fades form 1 to 0 + float fade {1.f}; + }; + +} // Components + +static float lerp(float a, float b, float t) { + return a + t * (b - a); +} + ChatGui4::ChatGui4( ConfigModelI& conf, RegistryMessageModel& rmm, @@ -167,6 +181,22 @@ void ChatGui4::render(void) { //ImGui::TableNextRow(0, TEXT_BASE_HEIGHT); Message3Registry& msg_reg = *msg_reg_ptr; + + // do systems TODO: extract + { // fade system + std::vector to_remove; + msg_reg.view().each([&to_remove](const Message3 e, Components::UnreadFade& fade) { + // TODO: configurable + const float fade_duration = 7.5f; + // TODO: dynamic fps + fade.fade -= 1.f/fade_duration * (1.f/60.f); + if (fade.fade <= 0.f) { + to_remove.push_back(e); + } + }); + msg_reg.remove(to_remove.cbegin(), to_remove.cend()); + } + msg_reg.view() .use() .each([&](const Message3 e, Message::Components::ContactFrom& c_from, Message::Components::ContactTo& c_to, Message::Components::Timestamp ts @@ -184,6 +214,15 @@ void ChatGui4::render(void) { ImGui::TextUnformatted(""); } + // use username as visibility test + if (ImGui::IsItemVisible() && msg_reg.all_of(e)) { + // get time now + const uint64_t ts_now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + msg_reg.emplace_or_replace(e, ts_now); + msg_reg.remove(e); + msg_reg.emplace_or_replace(e, 1.f); + } + // highlight self if (_cr.any_of(c_from.c)) { ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.7f, 0.3f, 0.20f)); @@ -194,10 +233,31 @@ void ChatGui4::render(void) { //ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color); } + std::optional row_bg; + // private group message if (_cr.any_of(c_to.c)) { - ImU32 row_bg_color = ImGui::GetColorU32(ImVec4(0.5f, 0.2f, 0.5f, 0.35f)); - ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color); + const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f); + ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color); + row_bg = priv_msg_hi_col; + } + + // fade + if (msg_reg.all_of(e)) { + ImVec4 hi_color = ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogramHovered); + hi_color.w = 0.8f; + const ImVec4 orig_color = row_bg.value_or(ImGui::GetStyleColorVec4(ImGuiCol_TableRowBg)); // imgui defaults to 0,0,0,0 + const float fade_frac = msg_reg.get(e).fade; + + ImVec4 res_color{ + lerp(orig_color.x, hi_color.x, fade_frac), + lerp(orig_color.y, hi_color.y, fade_frac), + lerp(orig_color.z, hi_color.z, fade_frac), + lerp(orig_color.w, hi_color.w, fade_frac), + }; + + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::GetColorU32(res_color)); } } @@ -588,7 +648,14 @@ bool ChatGui4::renderContactListContactBig(const Contact3 c, const bool selected ImGui::SameLine(); ImGui::BeginGroup(); { - ImGui::Text("%s", (_cr.all_of(c) ? _cr.get(c).name.c_str() : "")); + // TODO: is there a better way? + // maybe cache mm? + bool has_unread = false; + if (const auto* mm = _rmm.get(c); mm != nullptr && !mm->storage().empty()) { + has_unread = true; + } + + ImGui::Text("%s%s", has_unread?"* ":"", (_cr.all_of(c) ? _cr.get(c).name.c_str() : "")); if (request_incoming) { ImGui::TextUnformatted("Incoming request/invite"); } else if (request_outgoing) { diff --git a/src/main_screen.cpp b/src/main_screen.cpp index 740310b..df8b4a5 100644 --- a/src/main_screen.cpp +++ b/src/main_screen.cpp @@ -85,9 +85,7 @@ Screen* MainScreen::poll(bool& quit) { cg.render(); if constexpr (false) { - bool open = !quit; - ImGui::ShowDemoWindow(&open); - quit = !open; + ImGui::ShowDemoWindow(); } #if 0